#include "operatorimporter.h"
#include <QFont>
#include <QFontMetrics>
#include <QString>

OperatorImporter::OperatorImporter(QObject *parent) : QObject(parent)
{
    m_hash["int8"]="short";
    m_hash["int16"]="short";
    m_hash["int32"]="int";
    m_hash["float32"]="float";
    m_hash["float64"]="real";
    m_hash["uint8"]="ushort";
    m_hash["uint16"]="ushort";
    m_hash["uint32"]="uint";
}

void OperatorImporter::dataProcess(OperatorData &datas,QDomDocument &doc)
{

    //操作符变量处理
    variableProcess(datas.variables,doc);

    //状态机变量处理
    for(auto state:datas.stmModel.states())
    {
        variableProcess(state.variables,doc);
        datas.stmModel.addState(state.scadeOid,state);
    }

    statemachineProcess(doc);

    //ifblock变量处理
    for(auto action:datas.blockModel.actionMap)
    {
        variableProcess(action.variables,doc);
        datas.blockModel.actionMap.insert(action.scadeOid,action);
    }

    ifblockProcess();

    //页面处理
    int EleID=0;

    for(int i=0;i<datas.diagrams.size();i++)
    {
        diagramProcess(datas.diagrams[i],EleID);
    }

    for(auto stateOid:datas.stmModel.states().keys())
    {
        State state=*datas.stmModel.getState(stateOid);

        for(auto& pou:state.pouList)
        {
            diagramProcess(pou.dia,EleID);
        }

        datas.stmModel.addState(state.redaceOid,state);
    }

    for(auto& action:datas.blockModel.actionMap)
    {
        for(auto& pou:action.pouList)
        {
            diagramProcess(pou.dia,EleID);
        }
    }

    //数据流的逻辑处理
    dataStreamEquationProcess(datas,doc);

    //状态机状态内行为逻辑处理
    stmEquationProcess(doc);

    //ifblock的Action内行为逻辑处理
    blockEquationProcess(doc);
}

void OperatorImporter::variableXmlAddOperator(QDomElement& Variables,QDomDocument& doc,OperatorData &datas)
{
    bool hasVar=false;

    if(!datas.variables.isEmpty())
    {
        hasVar=true;
    }

    for(auto state:datas.stmModel.states().values())
    {
        if(!state.variables.isEmpty())
        {
            hasVar=true;
        }
    }

    if(hasVar)
    {
        QDomElement operatorEle=doc.createElement("Operator");
        operatorEle.setAttribute("id",datas.redaceOid);

        bool hasInput=false;
        bool hasOutput=false;
        bool hasSignal=false;
        bool hasLocal=false;

        for(int i=0;i<datas.variables.size();i++)
        {
            if(datas.variables.at(i).type=="input")
            {
                hasInput=true;
            }

            if(datas.variables.at(i).type=="output")
            {
                hasOutput=true;
            }

            if(datas.variables.at(i).type=="signal")
            {
                hasSignal=true;
            }

            if(datas.variables.at(i).type=="local")
            {
                hasLocal=true;
            }
        }

        for(auto state:datas.stmModel.states().values())
        {
            for(auto var:state.variables)
            {
                if(var.type=="local")
                {
                    hasLocal=true;
                }

                if(var.type=="signal")
                {
                    hasSignal=true;
                }
            }

        }

        if(hasInput==true)
        {
            QDomElement inputsEle=doc.createElement("inputs");

            for(int j=0;j<datas.variables.size();j++)
            {
                if(datas.variables.at(j).type=="input")
                    inputsEle.appendChild(datas.variables.at(j).node);
            }

            operatorEle.appendChild(inputsEle);
        }

        if(hasOutput==true)
        {
            QDomElement outputsEle=doc.createElement("outputs");
            for(int j=0;j<datas.variables.size();j++)
            {
                if(datas.variables.at(j).type=="output")
                    outputsEle.appendChild(datas.variables.at(j).node);
            }

            operatorEle.appendChild(outputsEle);
        }

        if(hasSignal==true)
        {
            QDomElement signalsEle=doc.createElement("signals");

            for(int j=0;j<datas.variables.size();j++)
            {
                if(datas.variables.at(j).type=="signal")
                    signalsEle.appendChild(datas.variables.at(j).node);

            }

            for(auto state:datas.stmModel.states().values())
            {
                bool hasSig=false;
                for(auto var:state.variables)
                {
                    if(var.type=="signal")
                    {
                        hasSig=true;
                    }
                }

                if(hasSig)
                {
                    QDomElement stateEle=doc.createElement("State");
                    stateEle.setAttribute("id",state.redaceOid);
                    QDomElement stateSignalsEle=doc.createElement("signals");
                    stateEle.appendChild(stateSignalsEle);

                    for(auto var:state.variables)
                    {
                        if(var.type=="signal")
                        {
                            stateSignalsEle.appendChild(var.node);
                        }
                    }

                    signalsEle.appendChild(stateEle);
                }

            }

            operatorEle.appendChild(signalsEle);
        }

        if(hasLocal==true)
        {
            QDomElement localsEle=doc.createElement("locals");

            for(int j=0;j<datas.variables.size();j++)
            {
                if(datas.variables.at(j).type=="local")
                    localsEle.appendChild(datas.variables.at(j).node);

            }

            for(auto state:datas.stmModel.states().values())
            {
                bool hasLoc=false;
                for(auto var:state.variables)
                {
                    if(var.type=="local")
                    {
                        hasLoc=true;
                    }
                }

                if(hasLoc)
                {
                    QDomElement stateEle=doc.createElement("State");
                    stateEle.setAttribute("id",state.redaceOid);
                    QDomElement stateLocalsEle=doc.createElement("locals");
                    stateEle.appendChild(stateLocalsEle);

                    for(auto var:state.variables)
                    {
                        if(var.type=="local")
                        {
                            stateLocalsEle.appendChild(var.node);
                        }
                    }

                    localsEle.appendChild(stateEle);
                }

            }

            operatorEle.appendChild(localsEle);
        }
        Variables.appendChild(operatorEle);

    }

}

void OperatorImporter::ifblockDataXmlAddOperator(QDomElement &IfBlocks, QDomDocument &doc)
{
    if(m_operator.blockModel.ifblockList.isEmpty())
    {
        return;
    }

    QDomElement operatorEle=doc.createElement("Operator");
    operatorEle.setAttribute("id",m_operator.redaceOid);
    IfBlocks.appendChild(operatorEle);

    //ifblcok
    QDomElement ifblockEle=doc.createElement("ifblock");
    operatorEle.appendChild(ifblockEle);

    for(auto block:m_operator.blockModel.ifblockList)
    {
        QDomElement blockItemEle=doc.createElement("Variable");
        blockItemEle.setAttribute("name",block.name);
        ifblockEle.appendChild(blockItemEle);

        QDomElement typeEle1=doc.createElement("type");
        blockItemEle.appendChild(typeEle1);

        QDomElement namedTypeEle=doc.createElement("NamedType");
        typeEle1.appendChild(namedTypeEle);

        QDomElement typeEle2=doc.createElement("type");
        namedTypeEle.appendChild(typeEle2);

        QDomElement typeRefEle=doc.createElement("TypeRef");
        typeRefEle.setAttribute("name","bool");
        typeEle2.appendChild(typeRefEle);

        QDomElement oidEle=doc.createElement("oid");
        oidEle.setAttribute("value",block.redaceOid);
        blockItemEle.appendChild(oidEle);

        QDomElement IfBlockInfosEle=doc.createElement("IfBlockInfos");
        blockItemEle.appendChild(IfBlockInfosEle);

        QDomElement variableBlockEle=doc.createElement("variableBlock");
        variableBlockEle.setAttribute("value",block.redaceOid);
        IfBlockInfosEle.appendChild(variableBlockEle);

        QDomElement variableParentEle=doc.createElement("variableParent");
        variableParentEle.setAttribute("value",m_operator.redaceOid);
        IfBlockInfosEle.appendChild(variableParentEle);
    }

    //ifnode
    if(m_operator.blockModel.ifNodeMap.size()>1)
    {
        QDomElement ifnodeEle=doc.createElement("ifnode");
        operatorEle.appendChild(ifnodeEle);

        for(auto block:m_operator.blockModel.ifblockList)
        {
            IfNode rootNode=m_operator.blockModel.ifNodeMap.value(block.ifNodeOid);
            ifblockDataXmlAddIfnode(block,rootNode,ifnodeEle,doc);
        }
    }

    //action
    QDomElement actionEle=doc.createElement("action");
    operatorEle.appendChild(actionEle);

    for(auto block:m_operator.blockModel.ifblockList)
    {
        IfNode rootNode=m_operator.blockModel.ifNodeMap.value(block.ifNodeOid);
        ifblockDataXmlAddAction(block,rootNode,actionEle,doc);
    }

    //signals,locals
    bool existSig=false;
    bool existloc=false;
    for(auto action:m_operator.blockModel.actionMap)
    {
        for(auto var:action.variables)
        {
            if(var.type=="signal")
            {
                existSig=true;
            }

            if(var.type=="local")
            {
                existloc=true;
            }
        }
    }

    //signals
    if(existSig)
    {
        QDomElement signalsEle=doc.createElement("signals");
        operatorEle.appendChild(signalsEle);

        for(auto action:m_operator.blockModel.actionMap)
        {
            for(auto var:action.variables)
            {
                if(var.type=="signal")
                {
                    QDomElement signalItemEle=doc.createElement("Signal");
                    signalItemEle.setAttribute("name",var.name);
                    signalsEle.appendChild(signalItemEle);

                    QDomElement oidEle=doc.createElement("oid");
                    oidEle.setAttribute("value",var.id);
                    signalItemEle.appendChild(oidEle);

                    QDomElement IfBlockInfosEle=doc.createElement("IfBlockInfos");
                    signalItemEle.appendChild(IfBlockInfosEle);

                    QDomElement variableBlockEle=doc.createElement("variableBlock");
                    variableBlockEle.setAttribute("value",getIfblockFromActionOid(action.redaceOid));
                    IfBlockInfosEle.appendChild(variableBlockEle);

                    QDomElement variableParentEle=doc.createElement("variableParent");
                    variableParentEle.setAttribute("value",action.redaceOid);
                    IfBlockInfosEle.appendChild(variableParentEle);
                }
            }
        }
    }

    //locals
    if(existloc)
    {
        QDomElement localsEle=doc.createElement("locals");
        operatorEle.appendChild(localsEle);

        for(auto action:m_operator.blockModel.actionMap)
        {
            for(auto var:action.variables)
            {
                if(var.type=="local")
                {
                    QDomNode node=var.node.cloneNode(true);
                    localsEle.appendChild(node);

                    QDomElement IfBlockInfosEle=doc.createElement("IfBlockInfos");
                    node.appendChild(IfBlockInfosEle);

                    QDomElement variableBlockEle=doc.createElement("variableBlock");
                    variableBlockEle.setAttribute("value",getIfblockFromActionOid(action.redaceOid));
                    IfBlockInfosEle.appendChild(variableBlockEle);

                    QDomElement variableParentEle=doc.createElement("variableParent");
                    variableParentEle.setAttribute("value",action.redaceOid);
                    IfBlockInfosEle.appendChild(variableParentEle);
                }
            }
        }
    }

}

void OperatorImporter::ifblockDataXmlAddIfnode(const IfBlock &block, const IfNode &node,QDomElement& ifnodeEle,QDomDocument& doc)
{
    if(node.thenFork.fork==IFNODE)
    {
        IfNode rootThenNode=m_operator.blockModel.ifNodeMap.value(node.thenFork.oid);
        QDomElement nodeVarEle=doc.createElement("Variable");
        nodeVarEle.setAttribute("name","Then");
        ifnodeEle.appendChild(nodeVarEle);

        QDomElement typeEle1=doc.createElement("type");
        nodeVarEle.appendChild(typeEle1);

        QDomElement namedTypeEle=doc.createElement("NamedType");
        typeEle1.appendChild(namedTypeEle);

        QDomElement typeEle2=doc.createElement("type");
        namedTypeEle.appendChild(typeEle2);

        QDomElement typeRefEle=doc.createElement("TypeRef");
        typeRefEle.setAttribute("name","bool");
        typeEle2.appendChild(typeRefEle);

        QDomElement oidEle=doc.createElement("oid");
        oidEle.setAttribute("value",rootThenNode.redaceOid);
        nodeVarEle.appendChild(oidEle);

        QDomElement IfBlockInfosEle=doc.createElement("IfBlockInfos");
        nodeVarEle.appendChild(IfBlockInfosEle);

        QDomElement variableBlockEle=doc.createElement("variableBlock");
        variableBlockEle.setAttribute("value",block.redaceOid);
        IfBlockInfosEle.appendChild(variableBlockEle);

        QDomElement variableParentEle=doc.createElement("variableParent");
        variableParentEle.setAttribute("value",node.redaceOid);
        IfBlockInfosEle.appendChild(variableParentEle);

        QDomElement conditionEle=doc.createElement("condition");
        conditionEle.setAttribute("value",rootThenNode.condition);
        IfBlockInfosEle.appendChild(conditionEle);

        ifblockDataXmlAddIfnode(block,rootThenNode,ifnodeEle,doc);
    }

    if(node.elseFork.fork==IFNODE)
    {
        IfNode rootElseNode=m_operator.blockModel.ifNodeMap.value(node.elseFork.oid);
        QDomElement nodeVarEle=doc.createElement("Variable");
        nodeVarEle.setAttribute("name","Else");
        ifnodeEle.appendChild(nodeVarEle);

        QDomElement typeEle1=doc.createElement("type");
        nodeVarEle.appendChild(typeEle1);

        QDomElement namedTypeEle=doc.createElement("NamedType");
        typeEle1.appendChild(namedTypeEle);

        QDomElement typeEle2=doc.createElement("type");
        namedTypeEle.appendChild(typeEle2);

        QDomElement typeRefEle=doc.createElement("TypeRef");
        typeRefEle.setAttribute("name","bool");
        typeEle2.appendChild(typeRefEle);

        QDomElement oidEle=doc.createElement("oid");
        oidEle.setAttribute("value",rootElseNode.redaceOid);
        nodeVarEle.appendChild(oidEle);

        QDomElement IfBlockInfosEle=doc.createElement("IfBlockInfos");
        nodeVarEle.appendChild(IfBlockInfosEle);

        QDomElement variableBlockEle=doc.createElement("variableBlock");
        variableBlockEle.setAttribute("value",block.redaceOid);
        IfBlockInfosEle.appendChild(variableBlockEle);

        QDomElement variableParentEle=doc.createElement("variableParent");
        variableParentEle.setAttribute("value",node.redaceOid);
        IfBlockInfosEle.appendChild(variableParentEle);

        ifblockDataXmlAddIfnode(block,rootElseNode,ifnodeEle,doc);
    }
}

void OperatorImporter::ifblockDataXmlAddAction(const IfBlock &block, const IfNode &node, QDomElement &actionEle, QDomDocument &doc)
{
    if(node.thenFork.fork==ACTION)
    {
        BlockAction action=m_operator.blockModel.actionMap.value(node.thenFork.oid);
        QDomElement actionItemEle=doc.createElement("Variable");

        actionItemEle.setAttribute("name","Then");
        actionEle.appendChild(actionItemEle);

        QDomElement typeEle1=doc.createElement("type");
        actionItemEle.appendChild(typeEle1);

        QDomElement namedTypeEle=doc.createElement("NamedType");
        typeEle1.appendChild(namedTypeEle);

        QDomElement typeEle2=doc.createElement("type");
        namedTypeEle.appendChild(typeEle2);

        QDomElement typeRefEle=doc.createElement("TypeRef");
        typeRefEle.setAttribute("name","bool");
        typeEle2.appendChild(typeRefEle);

        QDomElement oidEle=doc.createElement("oid");
        oidEle.setAttribute("value",action.redaceOid);
        actionItemEle.appendChild(oidEle);

        QDomElement IfBlockInfosEle=doc.createElement("IfBlockInfos");
        actionItemEle.appendChild(IfBlockInfosEle);

        QDomElement variableBlockEle=doc.createElement("variableBlock");
        variableBlockEle.setAttribute("value",block.redaceOid);
        IfBlockInfosEle.appendChild(variableBlockEle);

        QDomElement variableParentEle=doc.createElement("variableParent");
        variableParentEle.setAttribute("value",node.redaceOid);
        IfBlockInfosEle.appendChild(variableParentEle);

        QDomElement conditionEle=doc.createElement("condition");
        conditionEle.setAttribute("value",node.condition);
        IfBlockInfosEle.appendChild(conditionEle);
    }

    if(node.thenFork.fork==IFNODE)
    {
        IfNode thenNode=m_operator.blockModel.ifNodeMap.value(node.thenFork.oid);
        ifblockDataXmlAddAction(block,thenNode,actionEle,doc);
    }

    if(node.elseFork.fork==ACTION)
    {
        BlockAction action=m_operator.blockModel.actionMap.value(node.elseFork.oid);
        QDomElement actionItemEle=doc.createElement("Variable");

        actionItemEle.setAttribute("name","Else");
        actionEle.appendChild(actionItemEle);

        QDomElement typeEle1=doc.createElement("type");
        actionItemEle.appendChild(typeEle1);

        QDomElement namedTypeEle=doc.createElement("NamedType");
        typeEle1.appendChild(namedTypeEle);

        QDomElement typeEle2=doc.createElement("type");
        namedTypeEle.appendChild(typeEle2);

        QDomElement typeRefEle=doc.createElement("TypeRef");
        typeRefEle.setAttribute("name","bool");
        typeEle2.appendChild(typeRefEle);

        QDomElement oidEle=doc.createElement("oid");
        oidEle.setAttribute("value",action.redaceOid);
        actionItemEle.appendChild(oidEle);

        QDomElement IfBlockInfosEle=doc.createElement("IfBlockInfos");
        actionItemEle.appendChild(IfBlockInfosEle);

        QDomElement variableBlockEle=doc.createElement("variableBlock");
        variableBlockEle.setAttribute("value",block.redaceOid);
        IfBlockInfosEle.appendChild(variableBlockEle);

        QDomElement variableParentEle=doc.createElement("variableParent");
        variableParentEle.setAttribute("value",node.redaceOid);
        IfBlockInfosEle.appendChild(variableParentEle);
    }

    if(node.elseFork.fork==IFNODE)
    {
        IfNode elseNode=m_operator.blockModel.ifNodeMap.value(node.elseFork.oid);
        ifblockDataXmlAddAction(block,elseNode,actionEle,doc);
    }
}

QString OperatorImporter::getIfblockFromActionOid(const QString actionOid)
{
    //获取所在的ifnode的oid
    QString parentNodeOid;
    for(auto node:m_operator.blockModel.ifNodeMap)
    {
        if(node.thenFork.oid==actionOid||node.elseFork.oid==actionOid)
        {
            parentNodeOid=node.redaceOid;
        }
    }

    for(auto block:m_operator.blockModel.ifblockList)
    {
        if(getIfNode(block,m_operator.blockModel.ifNodeMap.value(block.ifNodeOid),parentNodeOid))
        {
            return block.redaceOid;
        }
    }

    return QString();
}

bool OperatorImporter::getIfNode(const IfBlock &block, const IfNode &node,const QString& ifnodeOid)
{
    if(node.redaceOid==ifnodeOid)
    {
        return true;
    }
    else
    {
        if(node.thenFork.fork==IFNODE)
        {
            if(node.thenFork.oid==ifnodeOid)
            {
                return true;
            }
            else
            {
                if(getIfNode(block,m_operator.blockModel.ifNodeMap.value(node.thenFork.oid),ifnodeOid))
                {
                    return true;
                }
            }
        }

        if(node.elseFork.fork==IFNODE)
        {
            if(node.elseFork.oid==ifnodeOid)
            {
               return true;
            }
            else
            {
               if(getIfNode(block,m_operator.blockModel.ifNodeMap.value(node.elseFork.oid),ifnodeOid))
               {
                    return true;
               }
            }
        }

        return false;
    }
}

void OperatorImporter::ifblockReplaceXmlAddOperator(QDomElement &IfBlocks, QDomDocument &doc)
{
    if(m_operator.blockModel.ifblockList.isEmpty())
    {
        return;
    }

    QDomElement operatorEle=doc.createElement("Operator");
    operatorEle.setAttribute("id",m_operator.redaceOid);
    IfBlocks.appendChild(operatorEle);

    for(auto block:m_operator.blockModel.ifblockList)
    {
        IfNode rootNode=m_operator.blockModel.ifNodeMap.value(block.ifNodeOid);

        //ifblcok
        QDomElement ifblockEle=doc.createElement("IfBlock");
        ifblockEle.setAttribute("name",block.name);
        operatorEle.appendChild(ifblockEle);

        QDomElement blockEle=doc.createElement("block");
        ifblockEle.appendChild(blockEle);

        blockEle.appendChild(ifblockReplaceXmlAddIfnode(rootNode,doc));

        QDomElement oidEle=doc.createElement("oid");
        oidEle.setAttribute("value",block.redaceOid);
        ifblockEle.appendChild(oidEle);
    }
}

QDomElement OperatorImporter::ifblockReplaceXmlAddIfnode(const IfNode &node, QDomDocument &doc)
{
    QDomElement ifnodeEle=doc.createElement("IfNode");

    QDomElement ifEle=doc.createElement("if");
    ifnodeEle.appendChild(ifEle);
    ifEle.appendChild(node.conditionNode);

    QDomElement thenEle=doc.createElement("then");
    ifnodeEle.appendChild(thenEle);

    if(node.thenFork.fork==IFNODE)
    {
        IfNode thenNode=m_operator.blockModel.ifNodeMap.value(node.thenFork.oid);
        thenEle.appendChild(ifblockReplaceXmlAddIfnode(thenNode,doc));
    }

    if(node.thenFork.fork==ACTION)
    {
        BlockAction action=m_operator.blockModel.actionMap.value(node.thenFork.oid);
        thenEle.appendChild(ifblockReplaceXmlAddAction(action,doc));
    }

    QDomElement elseEle=doc.createElement("else");
    ifnodeEle.appendChild(elseEle);

    if(node.elseFork.fork==IFNODE)
    {
        IfNode elseNode=m_operator.blockModel.ifNodeMap.value(node.elseFork.oid);
        elseEle.appendChild(ifblockReplaceXmlAddIfnode(elseNode,doc));
    }

    if(node.elseFork.fork==ACTION)
    {
        BlockAction action=m_operator.blockModel.actionMap.value(node.elseFork.oid);
        elseEle.appendChild(ifblockReplaceXmlAddAction(action,doc));
    }

    QDomElement oidEle=doc.createElement("oid");
    oidEle.setAttribute("value",node.redaceOid);
    ifnodeEle.appendChild(oidEle);

    return ifnodeEle;
}

QDomElement OperatorImporter::ifblockReplaceXmlAddAction(const BlockAction &action, QDomDocument &doc)
{
    QDomElement actionEle=doc.createElement("Action");

    //signals,locals
    bool existSig=false;
    bool existloc=false;

    for(auto var:action.variables)
    {
        if(var.type=="signal")
        {
            existSig=true;
        }

        if(var.type=="local")
        {
            existloc=true;
        }
    }

    //signals
    if(existSig)
    {
        QDomElement signalsEle=doc.createElement("signals");
        actionEle.appendChild(signalsEle);

        for(auto var:action.variables)
        {
            if(var.type=="signal")
            {
               signalsEle.appendChild(var.node);
            }
        }
    }

    //locals
    if(existloc)
    {
        QDomElement localsEle=doc.createElement("locals");
        actionEle.appendChild(localsEle);

        for(auto var:action.variables)
        {
            if(var.type=="local")
            {
               localsEle.appendChild(var.node);
            }
        }
    }

    if(!action.equations.isEmpty())
    {
        QDomElement dataEle=doc.createElement("data");
        actionEle.appendChild(dataEle);

        for(auto equation:action.equations)
        {
            dataEle.appendChild(equation.node);
        }
    }

    QDomElement oidEle=doc.createElement("oid");
    oidEle.setAttribute("value",action.redaceOid);
    actionEle.appendChild(oidEle);

    return actionEle;
}

void OperatorImporter::generate_ifblock_dataFiles(const QString &redaceProjectPath, const QString &scadeProjectName)
{
    //创建ifblock文件夹
    QString ifblockDir=redaceProjectPath+"/"+scadeProjectName+"/ifblock";
    QDir dir(ifblockDir);
    if(!dir.exists())
        dir.mkdir(ifblockDir);

    QString filePath=redaceProjectPath+"/"+scadeProjectName+"/ifblock/ifblock_data.xml";
    QFile file(filePath);

    //文件不存在时
    if (!file.open(QFile::ReadOnly| QFile::Text))
    {
        if (!file.open(QFile::WriteOnly| QFile::Text|QFile::Truncate))
        {
            return;
        }

        QDomDocument doc;

        QDomProcessingInstruction instruction;

        instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
        doc.appendChild(instruction);

        QDomElement root = doc.documentElement();
        if(root.isNull())
        {
            root = doc.createElement("File");
            root.setAttribute("Type","IfBlock");

            QDomElement IfBlocks = doc.createElement("IfBlocks");

            ifblockDataXmlAddOperator(IfBlocks,doc);

            root.appendChild(IfBlocks);
        }

        doc.appendChild(root);

        QTextStream stream( &file );
        stream.setCodec("utf-8");
        doc.save(stream,2,QDomNode::EncodingFromTextStream);

        file.close();
    }
    else {

        QDomDocument doc;

        if(!doc.setContent(&file))
        {
            file.close();
            return;
        }

        file.close();

        QDomElement root = doc.documentElement();
        if(root.tagName()!="File")
        {
            return;
        }

        QDomElement IfBlocks = root.firstChild().toElement();
        if(IfBlocks.tagName()!="IfBlocks")
            return;

        ifblockDataXmlAddOperator(IfBlocks,doc);

        if(file.open(QFile::WriteOnly|QFile::Truncate))
        {
            QTextStream stream( &file );
            stream.setCodec("utf-8");
            doc.save(stream,2,QDomNode::EncodingFromTextStream);
        }

        file.close();
    }

    return;
}

void OperatorImporter::generate_ifblock_replaceFiles(const QString &redaceProjectPath, const QString &scadeProjectName)
{
    //创建ifblock文件夹
    QString ifblockDir=redaceProjectPath+"/"+scadeProjectName+"/ifblock";
    QDir dir(ifblockDir);
    if(!dir.exists())
        dir.mkdir(ifblockDir);

    QString filePath=redaceProjectPath+"/"+scadeProjectName+"/ifblock/ifblock_replace.xml";
    QFile file(filePath);

    //文件不存在时
    if (!file.open(QFile::ReadOnly| QFile::Text))
    {
        if (!file.open(QFile::WriteOnly| QFile::Text|QFile::Truncate))
        {
            return;
        }

        QDomDocument doc;

        QDomProcessingInstruction instruction;

        instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
        doc.appendChild(instruction);

        QDomElement root = doc.documentElement();
        if(root.isNull())
        {
            root = doc.createElement("File");
            root.setAttribute("Type","IfBlock");

            QDomElement IfBlocks = doc.createElement("IfBlocks");

            ifblockReplaceXmlAddOperator(IfBlocks,doc);

            root.appendChild(IfBlocks);
        }

        doc.appendChild(root);

        QTextStream stream( &file );
        stream.setCodec("utf-8");
        doc.save(stream,2,QDomNode::EncodingFromTextStream);

        file.close();
    }
    else {

        QDomDocument doc;

        if(!doc.setContent(&file))
        {
            file.close();
            return;
        }

        file.close();

        QDomElement root = doc.documentElement();
        if(root.tagName()!="File")
        {
            return;
        }

        QDomElement IfBlocks = root.firstChild().toElement();
        if(IfBlocks.tagName()!="IfBlocks")
            return;

        ifblockReplaceXmlAddOperator(IfBlocks,doc);

        if(file.open(QFile::WriteOnly|QFile::Truncate))
        {
            QTextStream stream( &file );
            stream.setCodec("utf-8");
            doc.save(stream,2,QDomNode::EncodingFromTextStream);
        }

        file.close();
    }

    return;
}

void OperatorImporter::generate_ifblock_GrammarFiles(const QString &redaceProjectPath, const QString &scadeProjectName)
{
    for(auto action:m_operator.blockModel.actionMap)
    {
        //创建文件夹
        QString blockDirPath=redaceProjectPath+"/"+scadeProjectName+"/POUs/"+m_operator.operatorName+"/ifblock";
        QDir dir(blockDirPath);
        if(!dir.exists())
            dir.mkpath(blockDirPath);//创建POUs文件夹

        for(auto pou:action.pouList)
        {
            QDomDocument doc;
            QDomProcessingInstruction header = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
            doc.appendChild(header);

            // 创建根元素 <File>
            QDomElement fileEle = doc.createElement("File");
            doc.appendChild(fileEle);
            fileEle.setAttribute("Type","Diagram");

            QDomElement operatorEle=doc.createElement("Operator");
            operatorEle.setAttribute("id",m_operator.redaceOid);
            fileEle.appendChild(operatorEle);

            for(int j=0;j<pou.dia.equations.size();j++)
            {
               operatorEle.appendChild(pou.dia.equations.at(j).node);
            }

            QString filePath=blockDirPath+"/"+pou.oid;
            QFile file(filePath);

            if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
               QTextStream stream(&file);
               stream.setCodec("UTF-8"); // 设置编码
               doc.save(stream, 2, QDomNode::EncodingFromDocument); // 缩进2空格
               file.close();
            }
        }



    }

}

void OperatorImporter::saveVariableFile(const QString &redaceProjectPath, const QString &scadeProjectName, OperatorData &datas)
{
    QString filePath=redaceProjectPath+"/"+scadeProjectName+"/variable.xml";
    QFile file(filePath);

    //变量文件不存在时
    if (!file.open(QFile::ReadOnly| QFile::Text))
    {
        if (!file.open(QFile::WriteOnly| QFile::Text|QFile::Truncate))
        {
            return;
        }

        QDomDocument doc;

        QDomProcessingInstruction instruction;

        instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
        doc.appendChild(instruction);

        QDomElement root = doc.documentElement();
        if(root.isNull())
        {
            root = doc.createElement("File");
            root.setAttribute("Type","Variable");

            QDomElement Variables = doc.createElement("Variables");

            variableXmlAddOperator(Variables,doc,datas);

            root.appendChild(Variables);
        }

        doc.appendChild(root);

        QTextStream stream( &file );
        stream.setCodec("utf-8");
        doc.save(stream,2,QDomNode::EncodingFromTextStream);

        file.close();
    }
    else {

        QDomDocument doc;

        if(!doc.setContent(&file))
        {
            file.close();
            return;
        }

        file.close();

        QDomElement root = doc.documentElement();
        if(root.tagName()!="File")
        {
            return;
        }

        QDomElement Variables = root.firstChild().toElement();
        if(Variables.tagName()!="Variables")
            return;

        variableXmlAddOperator(Variables,doc,datas);

        if(file.open(QFile::WriteOnly|QFile::Truncate))
        {
            QTextStream stream( &file );
            stream.setCodec("utf-8");
            doc.save(stream,2,QDomNode::EncodingFromTextStream);
        }

        file.close();
    }

    removeXmlComments(filePath);//删除变量节点中的所有注释节点，以便MODEN能成功加载
    return;
}



void OperatorImporter::correctionOperatorFile(QFile &file)
{
    //校正属性顺序
    QString strAll;
    QStringList strList;

    if(file.open(QIODevice::ReadOnly|QIODevice::Text))
    {
        QTextStream stream(&file);
        stream.setCodec("UTF-8");
        strAll=stream.readAll();
    }

    file.close();

    if(file.open(QIODevice::WriteOnly|QIODevice::Text))
    {
        QTextStream stream(&file);
        stream.setCodec("utf-8");
        strList=strAll.split("\n");

        for(int i=0;i<strList.size();i++)
        {
            //Operator的kind、external、name顺序
            if(strList.at(i).contains("Operator")&&strList.at(i).contains("kind=")&&strList.at(i).contains("name="))
            {
                int kindIndex=strList.at(i).indexOf("kind=");
                int nameIndex=strList.at(i).indexOf("name=");

                QString kindStr=strList.at(i).mid(kindIndex);
                QString nameStr=strList.at(i).mid(nameIndex);

                int kindEndIndex=kindStr.indexOf(" ")-1;
                int nameEndIndex=nameStr.indexOf(" ")-1;

                //导入操作符
                if(strList.at(i).contains("external="))
                {
                    int externalIndex=strList.at(i).indexOf("external=");

                    QString externalStr=strList.at(i).mid(externalIndex);

                    int externalEndIndex=externalStr.indexOf(" ")-1;

                    if(kindIndex>nameIndex&&kindIndex>externalIndex)
                    {
                        kindEndIndex=kindStr.indexOf(">")-1;

                    }

                    if(nameIndex>kindIndex&&nameIndex>externalIndex)
                    {
                        nameEndIndex=nameStr.indexOf(">")-1;
                    }

                    if(externalIndex>kindIndex&&externalIndex>nameIndex)
                    {
                        externalEndIndex=externalStr.indexOf(">")-1;
                    }

                    QString kindString=kindStr.mid(0,kindEndIndex+1);
                    QString externalString=externalStr.mid(0,externalEndIndex+1);
                    QString nameString=nameStr.mid(0,nameEndIndex+1);

                    strList[i]="    <Operator "+kindString+" "+externalString+" "+nameString+">";

                }
                else {
                    if(kindIndex>nameIndex)
                    {
                        kindEndIndex=kindStr.indexOf(">")-1;

                    }

                    if(nameIndex>kindIndex)
                    {
                        nameEndIndex=nameStr.indexOf(">")-1;
                    }

                    QString kindString=kindStr.mid(0,kindEndIndex+1);
                    QString nameString=nameStr.mid(0,nameEndIndex+1);

                    strList[i]="    <Operator "+kindString+" "+nameString+">";
                }

            }

            //组合运算操作符的name和operator顺序
            if(strList.at(i).contains("UnaryOp")||strList.at(i).contains("BinaryOp")||strList.at(i).contains("NAryOp"))
            {
                if(strList.at(i).contains("name=")&&strList.at(i).contains("operator="))
                {
                    int nameIndex=strList.at(i).indexOf("name=");
                    int operatorIndex=strList.at(i).indexOf("operator=");

                    if(nameIndex>operatorIndex)
                    {
                        QString str=strList.at(i).mid(operatorIndex);

                        int operatorEndIndex=str.indexOf(" ")-1;
                        int nameBeginIndex=operatorEndIndex+2;

                        QString operatorString=str.mid(0,operatorEndIndex+1);
                        QString nameString=str.mid(nameBeginIndex,str.length()-operatorString.length()-2);

                        strList[i]=strList.at(i).mid(0,operatorIndex-1)+" "+nameString+" "+operatorString+">";
                    }
                }
            }

            //高阶操作符的name和iterator顺序
            if(strList.at(i).contains("IteratorOp")||strList.at(i).contains("PartialIteratorOp"))
            {
                if(strList.at(i).contains("name=")&&strList.at(i).contains("iterator="))
                {
                    int nameIndex=strList.at(i).indexOf("name=");
                    int iteratorIndex=strList.at(i).indexOf("iterator=");

                    if(nameIndex>iteratorIndex)
                    {
                        QString str=strList.at(i).mid(iteratorIndex);

                        int iteratorEndIndex=str.indexOf(" ")-1;
                        int nameBeginIndex=iteratorEndIndex+2;

                        QString iteratorString=str.mid(0,iteratorEndIndex+1);
                        QString nameString=str.mid(nameBeginIndex,str.length()-iteratorString.length()-2);

                        strList[i]=strList.at(i).mid(0,iteratorIndex-1)+" "+nameString+" "+iteratorString+">";
                    }

                }
            }

            //'\x00'->'/x00'
            if(strList.at(i).contains("'\\x00'"))
            {
                strList[i].replace("'\\x00'","'/x00'");
            }


            stream<<strList.at(i)<<endl;
        }
    }

    file.close();
}

void OperatorImporter::saveOperatorFile(const QString &redaceProjectPath,const QString &scadeProjectName,const QString &operatorFileName,OperatorData &datas)
{    
    generateOperatorFileTemplate(redaceProjectPath,scadeProjectName,operatorFileName,datas);

    QString filePath=redaceProjectPath+"/"+scadeProjectName+"/"+operatorFileName;
    QFile file(filePath);    

    QDomDocument doc;

    if(!doc.setContent(&file))
    {
        file.close();
        return;
    }

    file.close();

    if(datas.isNew==false)
    {
        dataProcess(m_operator,doc);
    }

    saveVariableFile(redaceProjectPath,scadeProjectName,datas);

    QDomElement root = doc.documentElement();
    QDomElement declarations = root.firstChild().toElement();

    QDomNode operatorNode=declarations.firstChild();

    QDomNodeList itemList=operatorNode.childNodes();

    for(int i=0;i<itemList.size();i++)
    {
        //data
        if(itemList.at(i).toElement().tagName()=="data")
        {
            for(int j=0;j<datas.equations.size();j++)
            {
                operatorNode.childNodes().at(i).appendChild(datas.equations.at(j).node);

            }

            for(int j=0;j<datas.stmList.size();j++)
            {
                StateMachine stm=*datas.stmModel.getStateMachine(datas.stmList.at(j));

                QDomElement statemachineRefEle=doc.createElement("StateMachineRef");
                statemachineRefEle.setAttribute("name",stm.name);
                statemachineRefEle.setAttribute("filepath","/POUs/"+stm.hierarchy+"/"+stm.poufilename);
                statemachineRefEle.setAttribute("oid",stm.redaceOid);
                operatorNode.childNodes().at(i).appendChild(statemachineRefEle);
            }
        }

        //diagrams
        if(itemList.at(i).toElement().tagName()=="diagrams")
        {
            for(const auto &state:datas.stmModel.states())
            {
                for(auto pou:state.pouList)
                {
                    QDomElement NetDiagramEle=doc.createElement("NetDiagram");
                    NetDiagramEle.setAttribute("name",pou.name);
                    NetDiagramEle.setAttribute("landscape","");
                    NetDiagramEle.setAttribute("oid",pou.oid);
                    NetDiagramEle.setAttribute("stateName",state.name);
                    NetDiagramEle.setAttribute("DiagramType","statediagram");
                    NetDiagramEle.setAttribute("stateId",state.redaceOid);
                    NetDiagramEle.setAttribute("EleIDIndex","");
                    NetDiagramEle.setAttribute("OutPortIndex","");
                    NetDiagramEle.setAttribute("ProjectName","");
                    NetDiagramEle.setAttribute("DiagramName","");
                    NetDiagramEle.setAttribute("DiagramId","");
                    NetDiagramEle.setAttribute("Description","");
                    NetDiagramEle.setAttribute("DiagramNum","");
                    NetDiagramEle.setAttribute("DiagramVersion","");
                    NetDiagramEle.setAttribute("DesignPersonName","");
                    NetDiagramEle.setAttribute("DesignTime","");
                    NetDiagramEle.setAttribute("CheckPersonName","");
                    NetDiagramEle.setAttribute("CheckTime","");
                    NetDiagramEle.setAttribute("DeterminePersonName","");
                    NetDiagramEle.setAttribute("DetermineTime","");
                    NetDiagramEle.setAttribute("ApprovePersonName","");
                    NetDiagramEle.setAttribute("ApproveTime","");
                    NetDiagramEle.setAttribute("FDDiagram","False");
                    NetDiagramEle.setAttribute("BackgroundImageWidth","0");
                    NetDiagramEle.setAttribute("BackgroundImageHeight","0");
                    NetDiagramEle.setAttribute("BackgroundImageFileName","");
                    operatorNode.childNodes().at(i).appendChild(NetDiagramEle);
                }
            }

            for(auto action:datas.blockModel.actionMap)
            {
                for(auto pou:action.pouList)
                {
                    QDomElement NetDiagramEle=doc.createElement("NetDiagram");
                    NetDiagramEle.setAttribute("name",pou.name);
                    NetDiagramEle.setAttribute("landscape","");
                    NetDiagramEle.setAttribute("oid",pou.oid);
                    NetDiagramEle.setAttribute("IfBlockActionId",action.redaceOid);
                    NetDiagramEle.setAttribute("IfBlockId",getIfblockFromActionOid(action.redaceOid));
                    NetDiagramEle.setAttribute("stateName","");
                    NetDiagramEle.setAttribute("DiagramType","");
                    NetDiagramEle.setAttribute("stateId","");
                    NetDiagramEle.setAttribute("EleIDIndex","");
                    NetDiagramEle.setAttribute("OutPortIndex","");
                    NetDiagramEle.setAttribute("ProjectName","");
                    NetDiagramEle.setAttribute("DiagramName","");
                    NetDiagramEle.setAttribute("DiagramId","");
                    NetDiagramEle.setAttribute("Description","");
                    NetDiagramEle.setAttribute("DiagramNum","");
                    NetDiagramEle.setAttribute("DiagramVersion","");
                    NetDiagramEle.setAttribute("DesignPersonName","");
                    NetDiagramEle.setAttribute("DesignTime","");
                    NetDiagramEle.setAttribute("CheckPersonName","");
                    NetDiagramEle.setAttribute("CheckTime","");
                    NetDiagramEle.setAttribute("DeterminePersonName","");
                    NetDiagramEle.setAttribute("DetermineTime","");
                    NetDiagramEle.setAttribute("ApprovePersonName","");
                    NetDiagramEle.setAttribute("ApproveTime","");
                    NetDiagramEle.setAttribute("FDDiagram","False");
                    NetDiagramEle.setAttribute("BackgroundImageWidth","0");
                    NetDiagramEle.setAttribute("BackgroundImageHeight","0");
                    NetDiagramEle.setAttribute("BackgroundImageFileName","");
                    operatorNode.childNodes().at(i).appendChild(NetDiagramEle);
                }
            }
        }
    }

    if(file.open(QFile::WriteOnly|QFile::Truncate))
    {
        QTextStream stream( &file );
        stream.setCodec("utf-8");
        doc.save(stream,2,QDomNode::EncodingFromTextStream);
    }

    file.close();

    //校正属性顺序
    correctionOperatorFile(file);
    generate_ifblock_dataFiles(redaceProjectPath,scadeProjectName);    
    generate_ifblock_replaceFiles(redaceProjectPath,scadeProjectName);
    generate_ifblock_GrammarFiles(redaceProjectPath,scadeProjectName);
    generateStmPOUFiles();

    generateStmGrammarFiles();

    generateStateGrammarFiles();
}

bool OperatorImporter::readOperatorFile(const QDomNode &root)
{

    QDomElement element=root.toElement();
    m_operator.kind=element.attribute("kind");

    if(element.hasAttribute("external")&&element.attribute("external")=="imported")//判断是否为导入操作符
    {
        m_operator.isImported=true;
        m_operator.logList.append(m_operator.operatorName+"为导入操作符;");
    }


    QDomNodeList items = element.childNodes();
    for (int i = 0;i < items.count();i++)
    {
        QDomNode item = items.at(i);
        element = item.toElement();

        //获取参数列表(暂时只考虑一个参数的情况)
        if(element.tagName()=="sizeParameters")
        {
            QDomNodeList paraList=element.childNodes();
            for(int i=0;i<paraList.size();i++)
            {
                if(paraList.at(i).toElement().tagName()=="SizeParameter")
                {
                    QString paraName=paraList.at(i).toElement().attribute("name");

                    m_operator.parameter=paraName;
                }
            }

            m_operator.hasPara=true;
            m_operator.logList.append("包含参数；");

        }

        //获取所有变量节点，解析变量数据
        if(element.tagName()=="inputs"||element.tagName()=="outputs"||element.tagName()=="locals")
        {
            m_operator.variables.append(parseVariables(element));
        }

        //信号量
        if(element.tagName()=="signals")
        {
            QDomNodeList signalList=element.childNodes();
            for(int j=0;j<signalList.size();j++)
            {
                QDomElement signalEle=signalList.at(j).toElement();
                m_operator.variables.append(parseSignal(signalEle));
            }
        }

        //获取所有逻辑节点，解析逻辑数据
        if(element.tagName()=="data")
        {
            parseDatas(element);
        }

        //解析pragmas节点，获取操作符oid和画面信息
        if(element.tagName()=="pragmas")
        {
            parsePragmas(element);
        }
    }

    return true;
}

void OperatorImporter::dataProcess_old(QFile &file,OperatorData &datas)
{
    if( !file.open(QIODevice::Append | QIODevice::Text) )
        return;

    QTextStream out(&file);

    //操作符oid修改
    datas.scadeOid=QUuid::createUuid().toString(QUuid::WithoutBraces);

    //变量处理
    QHash<QString,QString> hash;
    hash["int8"]="short";
    hash["int16"]="short";
    hash["int32"]="int";
    hash["float32"]="float";
    hash["float64"]="real";
    hash["uint8"]="ushort";
    hash["uint16"]="ushort";
    hash["uint32"]="uint";

    //变量数据类型转换，oid修改
    for(int i=0;i<datas.variables.size();i++)
    {
        datas.variables[i].id=QUuid::createUuid().toString(QUuid::WithoutBraces);
        //普通变量
        if(datas.variables.at(i).isArray==false&&datas.variables.at(i).isStruct==false)
        {
            if(hash.contains(datas.variables.at(i).dataType))
            {
                out<<QString("变量")+datas.variables.at(i).name+QString("的数据类型发生转换：")+datas.variables[i].dataType+QString("->")+hash.value(datas.variables.at(i).dataType)<<endl;
                datas.variables[i].dataType=hash.value(datas.variables.at(i).dataType);
            }
        }

        //结构体变量
        if(datas.variables.at(i).isStruct==true)
        {
            for(int j=0;j<datas.variables.at(i).fieldList.size();j++)
            {
                datas.variables[i].fieldList[j].oid=QUuid::createUuid().toString(QUuid::WithoutBraces);
                if(hash.contains(datas.variables.at(i).fieldList.at(j).type))
                {
                    datas.variables[i].fieldList[j].type=hash.value(datas.variables.at(i).fieldList.at(j).type);

                }

            }
        }

        //数组变量
        if(datas.variables.at(i).isArray==true&&hash.contains(datas.variables.at(i).array.type))
        {
            datas.variables[i].array.type=hash.value(datas.variables.at(i).array.type);
        }

    }

    //逻辑处理
    for(int i=0;i<datas.equations.size();i++)
    {
        datas.equations[i].redaceId=QUuid::createUuid().toString(QUuid::WithoutBraces);
    }

    file.close();

    //页面处理
    //diagramProcess(datas);
}

void OperatorImporter::diagramProcess(Diagram& diagram,int& EleID)
{

    QList<int> equationDelIndex;//被移除的图元的下标

    //图元。处理x,y,width,height,EleID;解析端口
    for(int j=0;j<diagram.equations.size();j++)
    {
        Equation equation=diagram.equations.at(j);

        //在画面中删除结束符和REDACE不支持的操作符
        if(equation.type=="terminator"||equation.isUnsupport==true)
        {
            equationDelIndex.append(j);
            //                diagram.equations.removeAt(j);
            continue;
        }

        equation.id=EleID;
        diagram.equations[j].id=EleID;

        EleID++;

        //图元坐标值缩小
        equation.x=equation.x/ZOOM;
        equation.y=equation.y/ZOOM;

        //宽高

        //输入变量、输出变量、本地变量、last变量
        if(equation.type=="inputVar"
            ||equation.type=="outputVar"
            ||equation.type=="localInputVar"
            ||equation.type=="localOutputVar"
            ||equation.type=="lastInputVar"
            ||equation.type=="lastOutputVar"
            ||equation.type=="lastLocalVar"
            ||equation.type=="presentSignal"
            ||equation.type=="lastSignal"
            ||equation.type=="emitSignal")
        {
            //                equation.width=70;
            equation.height=30;
            equation.text=equation.name;

            QFont font;
            font.setPointSize(10);
            QFontMetrics fontMetrics(font);
            QRectF textRect = fontMetrics.boundingRect(equation.text);

            equation.width=20+textRect.width();

            if(equation.type=="inputVar")
            {
                equation.eleType="ELETYPE_IN_VAR";
                equation.x=equation.x-equation.width;

                int gap=equation.height/2;
                portCoordinate outport;
                outport.type="out";
                outport.x=equation.x+equation.width;
                outport.y=equation.y+gap-5;
                equation.outList.append(outport);
            }

            if(equation.type=="outputVar")
            {
                equation.eleType="ELETYPE_OUT_VAR";

                int gap=equation.height/2;
                portCoordinate inport;
                inport.type="in";
                inport.x=equation.x;
                inport.y=equation.y+gap-5;
                equation.inList.append(inport);

                equation.rightList.append(equation.inList);
            }

            if(equation.type=="localInputVar")
            {
                equation.eleType="ELETYPE_LOCAL_IN_VAR";

                equation.x=equation.x-equation.width;

                int gap=equation.height/2;
                portCoordinate outport;
                outport.type="out";
                outport.x=equation.x+equation.width;
                outport.y=equation.y+gap-5;
                equation.outList.append(outport);
            }

            if(equation.type=="localOutputVar")
            {
                equation.eleType="ELETYPE_LOCAL_OUT_VAR";

                int gap=equation.height/2;
                portCoordinate inport;
                inport.type="in";
                inport.x=equation.x;
                inport.y=equation.y+gap-5;
                equation.inList.append(inport);

                equation.rightList.append(equation.inList);
            }

            if(equation.type=="lastInputVar")
            {
                equation.eleType="ELETYPE_IN_LAST_VAR";
                equation.x=equation.x-equation.width;
                textRect = fontMetrics.boundingRect("last '"+equation.text);
                equation.width=20+textRect.width();

                int gap=equation.height/2;
                portCoordinate outport;
                outport.type="out";
                outport.x=equation.x+equation.width;
                outport.y=equation.y+gap-5;
                equation.outList.append(outport);
            }

            if(equation.type=="lastOutputVar")
            {
                equation.eleType="ELETYPE_OUT_LAST_VAR";
                equation.x=equation.x-equation.width;
                textRect = fontMetrics.boundingRect("last '"+equation.text);
                equation.width=20+textRect.width();

                int gap=equation.height/2;
                portCoordinate outport;
                outport.type="out";
                outport.x=equation.x+equation.width;
                outport.y=equation.y+gap-5;
                equation.outList.append(outport);
            }

            if(equation.type=="lastLocalVar")
            {
                equation.eleType="ELETYPE_LOCAL_LAST_VAR";
                equation.x=equation.x-equation.width;
                textRect = fontMetrics.boundingRect("last '"+equation.text);
                equation.width=20+textRect.width();

                int gap=equation.height/2;
                portCoordinate outport;
                outport.type="out";
                outport.x=equation.x+equation.width;
                outport.y=equation.y+gap-5;
                equation.outList.append(outport);
            }

            //信号量
            if(equation.type=="presentSignal")
            {
                equation.eleType="ELETYPE_SIGNAL_PRESENT_VAR";
                equation.x=equation.x-equation.width;

                int gap=equation.height/2;
                portCoordinate outport;
                outport.type="out";
                outport.x=equation.x+equation.width;
                outport.y=equation.y+gap-5;
                equation.outList.append(outport);
            }

            if(equation.type=="lastSignal")
            {
                equation.eleType="ELETYPE_SIGNAL_LAST_VAR";
                equation.x=equation.x-equation.width;
                textRect = fontMetrics.boundingRect("last '"+equation.text);
                equation.width=20+textRect.width();

                int gap=equation.height/2;
                portCoordinate outport;
                outport.type="out";
                outport.x=equation.x+equation.width;
                outport.y=equation.y+gap-5;
                equation.outList.append(outport);
            }

            if(equation.type=="emitSignal")
            {
                equation.eleType="ELETYPE_SIGNAL_EMIT_VAR";

                int gap=equation.height/2;
                portCoordinate inport;
                inport.type="in";
                inport.x=equation.x;
                inport.y=equation.y+gap-5;
                equation.inList.append(inport);

                equation.rightList.append(equation.inList);
            }
        }

        //立即数
        if(equation.type=="immediate")
        {
            //处理cast立即数
            castImmediateProcess(equation.text);

            //整数或浮点数加后缀
            QMap<QString,QString> suffix;
            suffix["int8"]="s";
            suffix["int16"]="s";
            suffix["int64"]="l";
            suffix["float32"]="f";
            suffix["uint8"]="us";
            suffix["uint16"]="us";
            suffix["uint32"]="u";
            suffix["uint64"]="ul";

            QRegularExpression regex("^[-+]?\\d+$");//整数

            if(suffix.contains(equation.immediateType))
            {
                if(regex.match(equation.text).hasMatch()&&equation.immediateType=="float32")
                {
                    equation.text=equation.text+".0"+suffix[equation.immediateType];
                }
                else
                {
                    equation.text+=suffix[equation.immediateType];
                }
            }

            //real类型如果没有小数点，加上小数.0
            if(regex.match(equation.text).hasMatch()&&equation.immediateType=="float64")
            {
                equation.text=equation.text+".0";
            }

            QFont font;
            font.setPointSize(10);
            QFontMetrics fontMetrics(font);
            QRectF textRect = fontMetrics.boundingRect(equation.text);

            equation.width=32+textRect.width();
            //equation.width=32+4*equation.text.length();
            equation.height=30;

            equation.x=equation.x-equation.width;

            equation.eleType="ELETYPE_IMMEDIATE";
            //                equation.text=equation.rightVarRef;

            int gap=equation.height/2;
            portCoordinate outport;
            outport.type="out";
            outport.x=equation.x+equation.width;
            outport.y=equation.y+gap-5;
            equation.outList.append(outport);

        }

        //常量
        if(equation.type=="constant")
        {
            //                equation.width=72;
            equation.height=30;

            equation.eleType="ELETYPE_CONST";
            equation.text=equation.name;

            QFont font;
            font.setPointSize(10);
            QFontMetrics fontMetrics(font);
            QRectF textRect = fontMetrics.boundingRect(equation.text);

            equation.width=20+textRect.width();
            //equation.width=32+6*equation.text.length();

            equation.x=equation.x-equation.width;

            int gap=equation.height/2;
            portCoordinate outport;
            outport.type="out";
            outport.x=equation.x+equation.width;
            outport.y=equation.y+gap-5;
            equation.outList.append(outport);
        }

        //非高阶操作符
        if(equation.type=="operator")
        {
            if(equation.operatorType!="IteratorOp"&&equation.operatorType!="PartialIteratorOp"&&equation.operatorType!="OpCall")
            {
                equation.width=70;
                equation.height=84;

                if(equation.operatorType=="IfThenElseOp"||equation.operatorType=="CaseOp")
                {
                    equation.width=70;
                    equation.height=84;
                }
            }
            else
            {
                equation.width=120;
                equation.height=134;
            }

            //获取操作符端口
            parseEquationPorts(equation);

        }

        diagram.equations[j]=equation;
    }

    //移除所有需要移除的图元，如结束符和REDACE不支持的操作符
    for(int i=equationDelIndex.size()-1;i>=0;i--)
    {
        diagram.equations.removeAt(equationDelIndex.at(i));
    }

    QList<int> lineDelIndex;//需要移除的连接线的下标

    //处理连接线，获取连接线起点和终点
    for(int j=0;j<diagram.lineList.size();j++)
    {
        Line line;
        line=diagram.lineList.at(j);

        line.id=EleID;
        diagram.lineList[j].id=EleID;

        //            EleID=EleID+2*datas.diagrams[i].lineList[j].lineLengthList.size()+1;

        //连接线左右图元
        Equation leftEquation;
        Equation rightEquation;

        for(int k=0;k<diagram.equations.size();k++)
        {
            if(diagram.equations.at(k).oid==line.leftEquationOid)
                leftEquation=diagram.equations.at(k);

            if(diagram.equations.at(k).oid==line.rightEquationOid)
            {
                rightEquation=diagram.equations.at(k);
                //                    diagram.equations[k].linkId=EleID-1;
            }
        }

        //连接线的左或右端的图元找不到时
        if(rightEquation.type.isEmpty()||leftEquation.type.isEmpty())
        {
            lineDelIndex.append(j);
            //                diagram.lineList.removeAt(j);
            continue;
        }

        //times操作符特殊处理
        if(rightEquation.operatorType=="TimesOp")
        {
            if(line.rightIndex=="1")
            {
                line.rightIndex="2";
            }

            if(line.rightIndex=="2")
            {
                line.rightIndex="1";
            }
        }

        if(!rightEquation.rightList.isEmpty()){
            if(rightEquation.rightList.at(line.rightIndex.toInt()-1).type=="if"||rightEquation.rightList.at(line.rightIndex.toInt()-1).type=="para")
            {
                EleID=EleID+2*diagram.lineList[j].lineLengthList.size();
            }
            else {
                EleID=EleID+2*diagram.lineList[j].lineLengthList.size()+1;
            }
        }

        if(!leftEquation.outList.isEmpty()){
            //连接线起点
            line.beginX=leftEquation.outList.at(line.leftIndex.toInt()-1).x;
            line.beginY=leftEquation.outList.at(line.leftIndex.toInt()-1).y;
        }

        if(!rightEquation.rightList.isEmpty())
        {            
            //连接线终点
            line.endX=rightEquation.rightList.at(line.rightIndex.toInt()-1).x;
            line.endY=rightEquation.rightList.at(line.rightIndex.toInt()-1).y;

            rightEquation.rightList[line.rightIndex.toInt()-1].linkLine=line;                        
        }

        if(!diagram.equations.isEmpty()){
            for(int k=0;k<diagram.equations.size();k++)
            {
                if(diagram.equations.at(k).oid==rightEquation.oid)
                {
                    diagram.equations[k]=rightEquation;//保存rightEquation
                }
            }
        }


        //处理连接线的长度
        int hSum;
        int zSum;
        if(!rightEquation.rightList.isEmpty()){
            if(rightEquation.rightList.at(line.rightIndex.toInt()-1).type=="if"||rightEquation.rightList.at(line.rightIndex.toInt()-1).type=="para")
            {
                hSum=line.endX-line.beginX+5;
                zSum=line.endY-line.beginY-5;
            }
            else
            {
                hSum=line.endX-line.beginX;
                zSum=line.endY-line.beginY;
            }
        }


        if(!line.lineLengthList.isEmpty()){
            for(int k=0;k<line.lineLengthList.size();k++)
            {
                LineLength lineLength=line.lineLengthList.at(k);
                if(!rightEquation.rightList.isEmpty())
                {

                    if(rightEquation.rightList.at(line.rightIndex.toInt()-1).type=="if"||rightEquation.rightList.at(line.rightIndex.toInt()-1).type=="para")
                    {
                        if(k!=(line.lineLengthList.size()-1))
                        {
                            lineLength.hLength=lineLength.hLength/ZOOM;
                            lineLength.zLength=lineLength.zLength/ZOOM;
                            hSum=hSum-lineLength.hLength;
                            zSum=zSum-lineLength.zLength;
                        }
                        else {
                            lineLength.hLength=hSum;
                            lineLength.zLength=zSum;
                        }
                    }
                    else
                    {

                        if(k!=(line.lineLengthList.size()-1))
                        {
                            lineLength.hLength=lineLength.hLength/ZOOM;
                            lineLength.zLength=lineLength.zLength/ZOOM;
                            zSum=zSum-lineLength.zLength;
                        }
                        else
                        {
                            lineLength.hLength=lineLength.hLength/ZOOM;
                            lineLength.zLength=zSum;
                        }
                    }

                }
                line.lineLengthList[k]=lineLength;
            }
        }

        diagram.lineList[j]=line;
    }

    //删除需要删除的线
    for(int i=lineDelIndex.size()-1;i>=0;i--)
    {
        diagram.lineList.removeAt(lineDelIndex.at(i));
    }


}

void OperatorImporter::parseEquationPorts(Equation &data)
{
    //一元操作符
    if(data.operatorType=="UnaryOp")
        parseUnaryOpPorts(data);

    //二元操作符
    if(data.operatorType=="BinaryOp")
        parseBinaryOpPorts(data);

    if(data.operatorType=="TimesOp")
        parseTimesOpPorts(data);

    //lsl
    if(data.operatorType=="LslOp")
        parseLslOpPorts(data);

    //lsr
    if(data.operatorType=="LsrOp")
        parseLsrOpPorts(data);

    //多元操作符
    if(data.operatorType=="NAryOp")
        parseNAryOpPorts(data);

    //Previous
    if(data.operatorType=="PreOp")
        parsePreOpPorts(data);

    //Init
    if(data.operatorType=="InitOp")
        parseInitOpPorts(data);

    //Fby
    if(data.operatorType=="FbyOp")
        parseFbyOpPorts(data);

    //Prj
    if(data.operatorType=="PrjOp")
        parsePrjOpPorts(data);

    //Slice
    if(data.operatorType=="SliceOp")
        parseSliceOpPorts(data);

    //PrjDyn
    if(data.operatorType=="PrjDynOp")
        parsePrjDynOpPorts(data);

    //DataStruct
    if(data.operatorType=="DataStructOp")
        parseDataStructOpPorts(data);

    //ScalarToVector
    if(data.operatorType=="ScalarToVectorOp")
        parseScalarToVectorOpPorts(data);

    //DataArray
    if(data.operatorType=="DataArrayOp")
        parseDataArrayOpPorts(data);

    //ChgIthOp
    if(data.operatorType=="ChgIthOp")
        parseChgIthOpPorts(data);

    //IfThenElse
    if(data.operatorType=="IfThenElseOp")
        parseIfThenElseOpPorts(data);

    //Case
    if(data.operatorType=="CaseOp")
        parseCaseOpPorts(data);

    //Make
    if(data.operatorType=="MakeOp")
        parseMakeOpPorts(data);

    //Flatten
    if(data.operatorType=="FlattenOp")
        parseFlattenOpPorts(data);

    //NumericCast
    if(data.operatorType=="NumericCastOp")
        parseNumericCastOpPorts(data);

    //TransposeOp
    if(data.operatorType=="TransposeOp")
        parseTransposeOpPorts(data);

    //Boolean Activate
    if(data.operatorType=="ActivateOp")
        parseActivateOpPorts(data);

    //Restart
    if(data.operatorType=="RestartOp")
        parseRestartOpPorts(data);

    //Iterator
    if(data.operatorType=="IteratorOp")
        parseIteratorOpPorts(data);

    //PartialIterator
    if(data.operatorType=="PartialIteratorOp")
        parsePartialIteratorOpPorts(data);

    //OpCall
    if(data.operatorType=="OpCall")
        parseOpCallPorts(data);
}

void OperatorImporter::parseUnaryOpPorts(Equation &data)
{
    data.eleType="ELETYPE_OPERATOR";

    if(data.operatorName=="Unary Minus")
    {
        data.opeName="-";
        data.text="-";
    }

    if(data.operatorName=="Not")
    {
        data.opeName="not";
        data.text="not";
    }

    if(data.operatorName=="Convert To Integer")
    {
        data.opeName="INT";
        data.text="int";
    }

    if(data.operatorName=="Convert To Real")
    {
        data.opeName="REAL";
        data.text="real";
    }

    if(data.operatorName=="Reverse")
    {
        data.eleType="ELETYPE_STRUCTURE";
        data.opeName="Reverse";
        data.text="reverse";
    }

    if(data.operatorName=="Bitwise Not")
    {
        data.eleType="ELETYPE_BITWISE";
        data.opeName="lnot";
        data.text="";
    }

    int gap=data.height/2;
    portCoordinate inport;
    inport.type="in";
    inport.x=data.x;
    inport.y=data.y+gap-5;
    data.inList.append(inport);

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+gap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
}

void OperatorImporter::parseBinaryOpPorts(Equation &data)
{
    data.eleType="ELETYPE_OPERATOR";

    if(data.operatorName=="Minus")
    {
        data.opeName="+-";
        data.text="-";
    }

    if(data.operatorName=="Polymorphic Division")
    {
        data.opeName="pdiv";
        data.text="pdiv";
    }

    if(data.operatorName=="Integer Division")
    {
        data.opeName="div";
        data.text="div";
    }

    if(data.operatorName=="Modulo")
    {
        data.opeName="MOD";
        data.text="mod";
    }

    if(data.operatorName=="Strictly Less Than")
    {
        data.opeName="<";
        data.text="<";
    }

    if(data.operatorName=="Less Than Or Equal")
    {
        data.opeName="<=";
        data.text="<=";
    }

    if(data.operatorName=="Strictly Greater Than")
    {
        data.opeName=">";
        data.text=">";
    }

    if(data.operatorName=="Greater Than Or Equal")
    {
        data.opeName=">=";
        data.text=">=";
    }

    if(data.operatorName=="Different")
    {
        data.opeName="<>";
        data.text="<>";
    }

    if(data.operatorName=="Equal")
    {
        data.opeName="=";
        data.text="=";
    }

    if(data.operatorName=="Bitwise Exclusive Or")
    {
        data.eleType="ELETYPE_BITWISE";
        data.opeName="lxor";
        data.text="";
    }

    int lgap=data.height/3;
    int rgap=data.height/2;
    for(int i=0;i<2;i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+rgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
}

void OperatorImporter::parseNAryOpPorts(Equation &data)
{
    data.eleType="ELETYPE_OPERATOR";

    if(data.operatorName=="Plus")
    {
        data.opeName="++";
        data.text="+";
    }

    if(data.operatorName=="Multiplication")
    {
        data.opeName="*";
        data.text="*";
    }

    if(data.operatorName=="And")
    {
        data.opeName="and";
        data.text="and";
    }

    if(data.operatorName=="Or")
    {
        data.opeName="or";
        data.text="or";
    }

    if(data.operatorName=="Exclusive Or")
    {
        data.opeName="xor";
        data.text="xor";
    }

    if(data.operatorName=="Concatenation")
    {
        data.eleType="ELETYPE_STRUCTURE";
        data.opeName="Concatenation";
        data.text="concatenation";
    }

    if(data.operatorName=="Bitwise And")
    {
        data.opeName="land";
        data.text="";
    }

    if(data.operatorName=="Bitwise Or")
    {
        data.opeName="lor";
        data.text="";
    }

    int lgap=data.height/(data.nAryOp.constVarRefs.size()+1);
    int rgap=data.height/2;
    for(int i=0;i<data.nAryOp.constVarRefs.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+rgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
}

void OperatorImporter::parsePreOpPorts(Equation &data)
{
    data.eleType="ELETYPE_TIME";

    data.opeName="PreOp";
    data.text="";

    int gap=data.height/(data.lefts.size()+1);
    for(int i=0;i<data.preOp.flows.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+gap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<data.lefts.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+gap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.inList);

}

void OperatorImporter::parseInitOpPorts(Equation &data)
{
    data.eleType="ELETYPE_TIME";

    data.opeName="InitOp";
    data.text="";

    int zgap=data.height/(data.lefts.size()+1);
    int hgap=data.width/(data.lefts.size()+1);

    for(int i=0;i<data.initOp.flows.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+zgap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<data.initOp.parameters.size();i++)
    {
        portCoordinate paraport;
        paraport.type="para";

        paraport.paraValue=data.initOp.parameters.at(i).value;

        paraport.x=data.x+hgap*(i+1)-5;
        paraport.y=data.y+data.height;
        data.paraList.append(paraport);
    }

    for(int i=0;i<data.lefts.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+zgap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseFbyOpPorts(Equation &data)
{
    data.eleType="ELETYPE_TIME";

    data.opeName="FbyOp";
    data.text="";

    int zgap=data.height/(data.lefts.size()+1);
    int hgap=data.width/(data.fbyOp.parameters.size()+2);

    for(int i=0;i<data.fbyOp.flows.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+zgap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<(data.fbyOp.parameters.size()+1);i++)
    {
        portCoordinate paraport;
        paraport.type="para";
        if(i==0)
        {
            paraport.paraValue=data.fbyOp.delay.value;
        }
        else
        {
            paraport.paraValue=data.fbyOp.parameters.at(i-1).value;

        }

        paraport.x=data.x+hgap*(i+1)-5;
        paraport.y=data.y+data.height;
        data.paraList.append(paraport);
    }

    for(int i=0;i<data.lefts.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+zgap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parsePrjOpPorts(Equation &data)
{
    data.eleType="ELETYPE_STRUCTURE";

    data.opeName="PrjOp";
    data.text="";

    int zgap=data.height/2;
    int hgap=data.width/(data.prjOp.parameters.size()+1);

    portCoordinate inport;
    inport.type="in";
    inport.x=data.x;
    inport.y=data.y+zgap-5;
    data.inList.append(inport);

    for(int i=0;i<data.prjOp.parameters.size();i++)
    {
        portCoordinate paraport;
        paraport.type="para";
        paraport.paraValue=data.prjOp.parameters.at(i).value;

        paraport.x=data.x+hgap*(i+1)-5;
        paraport.y=data.y+data.height;
        data.paraList.append(paraport);
    }

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+zgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseSliceOpPorts(Equation &data)
{
    data.eleType="ELETYPE_STRUCTURE";

    data.opeName="SliceOp";
    data.text="";

    int zgap=data.height/2;
    int hgap=data.width/3;

    portCoordinate inport;
    inport.type="in";
    inport.x=data.x;
    inport.y=data.y+zgap-5;
    data.inList.append(inport);

    for(int i=0;i<2;i++)
    {
        portCoordinate paraport;
        paraport.type="para";
        if(i==0)
        {
            paraport.paraValue=data.sliceOp.fromIndex.value;
        }
        else {
            paraport.paraValue=data.sliceOp.toIndex.value;
        }

        paraport.x=data.x+hgap*(i+1)-5;
        paraport.y=data.y+data.height;
        data.paraList.append(paraport);
    }

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+zgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parsePrjDynOpPorts(Equation &data)
{
    data.eleType="ELETYPE_STRUCTURE";

    data.opeName="PrjDynOp";
    data.text="";

    int zgap=data.height/2;
    int hgap=data.width/(data.prjDynOp.indexes.size()+2);

    portCoordinate inport;
    inport.type="in";
    inport.x=data.x;
    inport.y=data.y+zgap-5;
    data.inList.append(inport);

    for(int i=0;i<(data.prjDynOp.indexes.size()+1);i++)
    {
        portCoordinate paraport;
        paraport.type="para";

        if(i!=data.prjDynOp.indexes.size())
        {
            paraport.paraValue=data.prjDynOp.indexes.at(i).value;
        }
        else {
            paraport.paraValue=data.prjDynOp.defaultpara.value;
        }

        paraport.x=data.x+hgap*(i+1)-5;
        paraport.y=data.y+data.height;
        data.paraList.append(paraport);
    }

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+zgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseDataStructOpPorts(Equation &data)
{
    data.eleType="ELETYPE_STRUCTURE";

    data.opeName="DataStructOp";
    data.text="";

    int lgap=data.height/(data.dataStructOp.labels.size()+1);
    int rgap=data.height/2;

    for(int i=0;i<data.dataStructOp.labels.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<data.dataStructOp.labels.size();i++)
    {
        portCoordinate paraport;
        paraport.type="para";
        paraport.paraValue=data.dataStructOp.labels.at(i).labelName;

        paraport.x=data.x;
        paraport.y=data.y+lgap*(i+1)-5;
        data.paraList.append(paraport);
    }

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+rgap-5;
    data.outList.append(outport);


    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseScalarToVectorOpPorts(Equation &data)
{
    data.eleType="ELETYPE_STRUCTURE";

    data.opeName="ScalarToVectorOp";
    data.text="";

    int zgap=data.height/(data.lefts.size()+1);
    int hgap=data.width/2;

    for(int i=0;i<data.scalarToVectorOp.flows.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+zgap*(i+1)-5;
        data.inList.append(inport);
    }

    portCoordinate paraport;
    paraport.type="para";
    paraport.paraValue=data.scalarToVectorOp.size.value;

    paraport.x=data.x+hgap-5;
    paraport.y=data.y+data.height;
    data.paraList.append(paraport);

    for(int i=0;i<data.lefts.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+zgap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);

}

void OperatorImporter::parseDataArrayOpPorts(Equation &data)
{
    data.eleType="ELETYPE_STRUCTURE";

    data.opeName="DataArrayOp";
    data.text="";

    int lgap=data.height/(data.dataArrayOp.datas.size()+1);
    int rgap=data.height/2;

    for(int i=0;i<data.dataArrayOp.datas.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+rgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
}

void OperatorImporter::parseChgIthOpPorts(Equation &data)
{
    data.eleType="ELETYPE_STRUCTURE";

    data.opeName="ChgIthOp";
    data.text="";

    int lgap=data.height/3;
    int hgap=data.width/(data.chgIthOp.parameters.size()+1);
    int rgap=data.height/2;

    for(int i=0;i<2;i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<data.chgIthOp.parameters.size();i++)
    {
        portCoordinate paraport;
        paraport.type="para";
        paraport.paraValue=data.chgIthOp.parameters.at(i).value;

        paraport.x=data.x+hgap*(i+1)-5;
        paraport.y=data.y+data.height;
        data.paraList.append(paraport);
    }

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+rgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseIfThenElseOpPorts(Equation &data)
{
    data.eleType="ELETYPE_CHOICE";

    data.opeName="IfThenElseOp";
    data.text="";

    int hgap=data.width/2;
    int lgap=data.height/(data.ifThenElseOp.thens.size()+data.ifThenElseOp.elses.size()+1);
    int rgap=data.height/(data.ifThenElseOp.thens.size()+1);

    portCoordinate ifport;
    ifport.type="if";
    ifport.x=data.x+hgap-5;
    ifport.y=data.y;
    data.ifList.append(ifport);

    for(int i=0;i<(data.ifThenElseOp.thens.size()+data.ifThenElseOp.elses.size());i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }


    for(int i=0;i<data.ifThenElseOp.thens.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+rgap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.ifList);
    data.rightList.append(data.inList);
}

void OperatorImporter::parseCaseOpPorts(Equation &data)
{
    data.eleType="ELETYPE_CHOICE";

    data.opeName="CaseOp";
    data.text="";

    int hgap=data.width/2;
    int lgap=data.height/(data.caseOp.cases.size()+2);
    int rgap=data.height/2;

    portCoordinate ifport;
    ifport.type="if";
    ifport.x=data.x+hgap-5;
    ifport.y=data.y;
    data.ifList.append(ifport);

    for(int i=0;i<(data.caseOp.cases.size()+1);i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<(data.caseOp.cases.size()+1);i++)
    {
        portCoordinate paraport;
        paraport.type="para";
        if(i!=data.caseOp.cases.size())
        {
            paraport.paraValue=data.caseOp.cases.at(i).labelName;
        }
        else
        {
            paraport.paraValue="Default";
        }

        paraport.x=data.x;
        paraport.y=data.y+lgap*(i+1)-5;
        data.paraList.append(paraport);
    }

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+rgap-5;
    data.outList.append(outport);

    data.rightList.append(data.ifList);
    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseMakeOpPorts(Equation &data)
{
    data.eleType="ELETYPE_STRUCTURE";

    data.opeName="MakeOp";
    data.text="";

    int lgap=data.height/(data.makeOp.calls.size()+1);
    int rgap=data.height/2;
    int hgap=data.width/2;

    for(int i=0;i<data.makeOp.calls.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    portCoordinate paraport;
    paraport.type="para";
    paraport.paraValue=data.makeOp.typeRef;

    paraport.x=data.x+hgap-5;
    paraport.y=data.y+data.height;
    data.paraList.append(paraport);

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+rgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseFlattenOpPorts(Equation &data)
{
    data.eleType="ELETYPE_STRUCTURE";

    data.opeName="FlattenOp";
    data.text="";

    int lgap=data.height/2;
    int rgap=data.height/(data.lefts.size()+1);
    int hgap=data.width/2;

    portCoordinate inport;
    inport.type="in";
    inport.x=data.x;
    inport.y=data.y+lgap-5;
    data.inList.append(inport);

    portCoordinate paraport;
    paraport.type="para";
    paraport.paraValue=data.flattenOp.typeRef;

    paraport.x=data.x+hgap-5;
    paraport.y=data.y+data.height;
    data.paraList.append(paraport);

    for(int i=0;i<data.lefts.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+rgap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseNumericCastOpPorts(Equation &data)
{
    data.eleType="ELETYPE_OPERATOR";
    data.opeName="NumericCastOp";
    data.text="";

    int lgap=data.height/2;
    int rgap=data.height/2;
    int hgap=data.width/2;

    portCoordinate inport;
    inport.type="in";
    inport.x=data.x;
    inport.y=data.y+lgap-5;
    data.inList.append(inport);

    portCoordinate paraport;
    paraport.type="para";
    if(m_hash.contains(data.numericCastOp.typeRef))
    {
        paraport.paraValue=m_hash[data.numericCastOp.typeRef];
    }
    else
    {
        paraport.paraValue=data.numericCastOp.typeRef;
    }

    paraport.x=data.x+hgap-5;
    paraport.y=data.y+data.height;
    data.paraList.append(paraport);

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+rgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseTimesOpPorts(Equation &data)
{
    data.eleType="ELETYPE_TIME";

    data.opeName="Times";
    data.text="";

    int zgap=data.height/2;
    int hgap=data.width/2;

    portCoordinate inport;
    inport.type="in";
    inport.x=data.x;
    inport.y=data.y+zgap-5;
    data.inList.append(inport);

    portCoordinate paraport;
    paraport.type="para";
    paraport.paraValue=data.timesOp.counter.value;
    paraport.x=data.x+hgap-5;
    paraport.y=data.y+data.height;
    data.paraList.append(paraport);

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+zgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseLslOpPorts(Equation &data)
{
    data.eleType="ELETYPE_BITWISE";

    data.opeName="lsl";
    data.text="";

    int zgap=data.height/2;
    int hgap=data.width/2;

    portCoordinate inport;
    inport.type="in";
    inport.x=data.x;
    inport.y=data.y+zgap-5;
    data.inList.append(inport);

    portCoordinate paraport;
    paraport.type="para";
    paraport.paraValue=data.lslOp.number.value;
    paraport.x=data.x+hgap-5;
    paraport.y=data.y+data.height;
    data.paraList.append(paraport);

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+zgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseLsrOpPorts(Equation &data)
{
    data.eleType="ELETYPE_BITWISE";

    data.opeName="lsr";
    data.text="";

    int zgap=data.height/2;
    int hgap=data.width/2;

    portCoordinate inport;
    inport.type="in";
    inport.x=data.x;
    inport.y=data.y+zgap-5;
    data.inList.append(inport);

    portCoordinate paraport;
    paraport.type="para";
    paraport.paraValue=data.lsrOp.number.value;
    paraport.x=data.x+hgap-5;
    paraport.y=data.y+data.height;
    data.paraList.append(paraport);

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+zgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseTransposeOpPorts(Equation &data)
{
    data.eleType="ELETYPE_STRUCTURE";

    data.opeName="Transpose";
    data.text="";

    int zgap=data.height/2;
    int hgap=data.width/3;

    portCoordinate inport;
    inport.type="in";
    inport.x=data.x;
    inport.y=data.y+zgap-5;
    data.inList.append(inport);

    for(int i=0;i<2;i++)
    {
        portCoordinate paraport;
        paraport.type="para";
        if(i==0)
        {
            paraport.paraValue=data.transposeOp.dimension1.value;
        }
        else {
            paraport.paraValue=data.transposeOp.dimension2.value;
        }

        paraport.x=data.x+hgap*(i+1)-5;
        paraport.y=data.y+data.height;
        data.paraList.append(paraport);
    }

    portCoordinate outport;
    outport.type="out";
    outport.x=data.x+data.width;
    outport.y=data.y+zgap-5;
    data.outList.append(outport);

    data.rightList.append(data.inList);
    data.rightList.append(data.paraList);
}

void OperatorImporter::parseActivateOpPorts(Equation &data)
{
    data.eleType="ELETYPE_HIGHER";
    data.opeName="Boolean Activate";
    if(data.activateOp.isInit)
    {
        data.text="ActivateOp";
    }
    else
    {
        data.text="ActivateNoInitOp";
    }

    //Unary Minus取反运算
    if(data.activateOp.operatorRef=="-$")
    {
        data.activateOp.usedIdName="-";
        data.activateOp.refName="-";
    }

    //Not非运算
    if(data.activateOp.operatorRef=="not$")
    {
        data.activateOp.usedIdName="not";
        data.activateOp.refName="not";
    }

    //Convert To Integer强制转换为整数运算
    if(data.activateOp.operatorRef=="int$")
    {
        data.activateOp.usedIdName="INT";
        data.activateOp.refName="int";
    }

    //Convert To Real强制转换换浮点数运算
    if(data.activateOp.operatorRef=="real$")
    {
        data.activateOp.usedIdName="REAL";
        data.activateOp.refName="real";
    }

    //Minus 减法运算
    if(data.activateOp.operatorRef=="$-$")
    {
        data.activateOp.usedIdName="+-";
        data.activateOp.refName="-";
    }

    //Polymorphic Division 除法运算（输出值为浮点数）
    if(data.activateOp.operatorRef=="$/$")
    {
        data.activateOp.usedIdName="pdiv";
        data.activateOp.refName="pdiv";
    }

    //Integer Division 除法运算（输出值为整数）
    if(data.activateOp.operatorRef=="$div$")
    {
        data.activateOp.usedIdName="div";
        data.activateOp.refName="div";
    }

    //Modulo 求余运算
    if(data.activateOp.operatorRef=="$mod$")
    {
        data.activateOp.usedIdName="MOD";
        data.activateOp.refName="mod";
    }

    //Strictly Less Than  <
    if(data.activateOp.operatorRef=="$<$")
    {
        data.activateOp.usedIdName="<";
        data.activateOp.refName="<";
    }

    //Less Than Or Equal   <=
    if(data.activateOp.operatorRef=="$<=$")
    {
        data.activateOp.usedIdName="<=";
        data.activateOp.refName="<=";
    }

    //Strictly Greater Than  >
    if(data.activateOp.operatorRef=="$>$")
    {
        data.activateOp.usedIdName=">";
        data.activateOp.refName=">";
    }

    //Greater Than Or Equal   >=
    if(data.activateOp.operatorRef=="$>=$")
    {
        data.activateOp.usedIdName=">=";
        data.activateOp.refName=">=";
    }

    //Different  !=
    if(data.activateOp.operatorRef=="$<>$")
    {
        data.activateOp.usedIdName="<>";
        data.activateOp.refName="<>";
    }

    //Equal    ==
    if(data.activateOp.operatorRef=="$=$")
    {
        data.activateOp.usedIdName="=";
        data.activateOp.refName="=";
    }

    //Plus加法运算
    if(data.activateOp.operatorRef=="$+$")
    {
        data.activateOp.usedIdName="++";
        data.activateOp.refName="+";
    }

    //Multiplication乘法运算
    if(data.activateOp.operatorRef=="$*$")
    {
        data.activateOp.usedIdName="*";
        data.activateOp.refName="*";
    }

    //And 与运算
    if(data.activateOp.operatorRef=="$and$")
    {
        data.activateOp.usedIdName="and";
        data.activateOp.refName="and";
    }

    //Or 或运算
    if(data.activateOp.operatorRef=="$or$")
    {
        data.activateOp.usedIdName="or";
        data.activateOp.refName="or";
    }

    //Exclusive Or异或运算
    if(data.activateOp.operatorRef=="$xor$")
    {
        data.activateOp.usedIdName="xor";
        data.activateOp.refName="xor";
    }

    //reverse
    if(data.activateOp.operatorRef=="reverse$")
    {
        data.activateOp.usedIdName="Reverse";
        data.activateOp.refName="reverse";
    }

    //Concatenation
    if(data.activateOp.operatorRef=="$@$")
    {
        data.activateOp.usedIdName="Concatenation";
        data.activateOp.refName="@";
    }

    //Times
    if(data.activateOp.operatorRef=="$times$")
    {
        data.activateOp.usedIdName="Times";
        data.activateOp.refName="times";
    }

    //land
    if(data.activateOp.operatorRef=="$land$")
    {
        data.activateOp.usedIdName="land";
        data.activateOp.refName="land";
    }

    //lor
    if(data.activateOp.operatorRef=="$lor$")
    {
        data.activateOp.usedIdName="lor";
        data.activateOp.refName="lor";
    }

    //lxor
    if(data.activateOp.operatorRef=="$lxor$")
    {
        data.activateOp.usedIdName="lxor";
        data.activateOp.refName="lxor";
    }

    //lnot
    if(data.activateOp.operatorRef=="lnot$")
    {
        data.activateOp.usedIdName="lnot";
        data.activateOp.refName="lnot";
    }

    //lsl
    if(data.activateOp.operatorRef=="$lsl$")
    {
        data.activateOp.usedIdName="lsl";
        data.activateOp.refName="lsl";
    }

    //lsr
    if(data.activateOp.operatorRef=="$lsr$")
    {
        data.activateOp.usedIdName="lsr";
        data.activateOp.refName="lsr";
    }

    //自定义操作符
    if(data.activateOp.isRef==true)
    {
        data.activateOp.usedIdName=data.activateOp.operatorRef;
        data.activateOp.refName=data.activateOp.operatorRef;
    }

    int hgap=data.width/2;
    int lgap=data.height/(data.activateOp.calls.size()+1);
    int rgap=data.height/(data.lefts.size()+1);
    int zgap=data.width/(data.activateOp.defaultValue.size()+1);

    portCoordinate ifport;
    ifport.type="if";
    ifport.x=data.x+hgap-5;
    ifport.y=data.y;
    data.ifList.append(ifport);

    for(int i=0;i<data.activateOp.calls.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<data.lefts.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+rgap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.ifList);
    data.rightList.append(data.inList);


    for(int i=0;i<data.activateOp.defaultValue.size();i++)
    {
        portCoordinate paraport;
        paraport.type="para";
        paraport.paraValue=data.activateOp.defaultValue.at(i).value;

        paraport.x=data.x+zgap*(i+1)-5;
        paraport.y=data.y+data.height;
        data.paraList.append(paraport);
    }

    data.rightList.append(data.paraList);    
}

void OperatorImporter::parseRestartOpPorts(Equation &data)
{
    data.eleType="ELETYPE_HIGHER";
    data.opeName="Restart";
    data.text="1";

    //Unary Minus取反运算
    if(data.restartOp.operatorRef=="-$")
    {
        data.restartOp.usedIdName="-";
        data.restartOp.refName="-";
    }

    //Not非运算
    if(data.restartOp.operatorRef=="not$")
    {
        data.restartOp.usedIdName="not";
        data.restartOp.refName="not";
    }

    //Convert To Integer强制转换为整数运算
    if(data.restartOp.operatorRef=="int$")
    {
        data.restartOp.usedIdName="INT";
        data.restartOp.refName="int";
    }

    //Convert To Real强制转换换浮点数运算
    if(data.restartOp.operatorRef=="real$")
    {
        data.restartOp.usedIdName="REAL";
        data.restartOp.refName="real";
    }

    //Minus 减法运算
    if(data.restartOp.operatorRef=="$-$")
    {
        data.restartOp.usedIdName="+-";
        data.restartOp.refName="-";
    }

    //Polymorphic Division 除法运算（输出值为浮点数）
    if(data.restartOp.operatorRef=="$/$")
    {
        data.restartOp.usedIdName="pdiv";
        data.restartOp.refName="pdiv";
    }

    //Integer Division 除法运算（输出值为整数）
    if(data.restartOp.operatorRef=="$div$")
    {
        data.restartOp.usedIdName="div";
        data.restartOp.refName="div";
    }

    //Modulo 求余运算
    if(data.restartOp.operatorRef=="$mod$")
    {
        data.restartOp.usedIdName="MOD";
        data.restartOp.refName="mod";
    }

    //Strictly Less Than  <
    if(data.restartOp.operatorRef=="$<$")
    {
        data.restartOp.usedIdName="<";
        data.restartOp.refName="<";
    }

    //Less Than Or Equal   <=
    if(data.restartOp.operatorRef=="$<=$")
    {
        data.restartOp.usedIdName="<=";
        data.restartOp.refName="<=";
    }

    //Strictly Greater Than  >
    if(data.restartOp.operatorRef=="$>$")
    {
        data.restartOp.usedIdName=">";
        data.restartOp.refName=">";
    }

    //Greater Than Or Equal   >=
    if(data.restartOp.operatorRef=="$>=$")
    {
        data.restartOp.usedIdName=">=";
        data.restartOp.refName=">=";
    }

    //Different  !=
    if(data.restartOp.operatorRef=="$<>$")
    {
        data.restartOp.usedIdName="<>";
        data.restartOp.refName="<>";
    }

    //Equal    ==
    if(data.restartOp.operatorRef=="$=$")
    {
        data.restartOp.usedIdName="=";
        data.restartOp.refName="=";
    }

    //Plus加法运算
    if(data.restartOp.operatorRef=="$+$")
    {
        data.restartOp.usedIdName="++";
        data.restartOp.refName="+";
    }

    //Multiplication乘法运算
    if(data.restartOp.operatorRef=="$*$")
    {
        data.restartOp.usedIdName="*";
        data.restartOp.refName="*";
    }

    //And 与运算
    if(data.restartOp.operatorRef=="$and$")
    {
        data.restartOp.usedIdName="and";
        data.restartOp.refName="and";
    }

    //Or 或运算
    if(data.restartOp.operatorRef=="$or$")
    {
        data.restartOp.usedIdName="or";
        data.restartOp.refName="or";
    }

    //Exclusive Or异或运算
    if(data.restartOp.operatorRef=="$xor$")
    {
        data.restartOp.usedIdName="xor";
        data.restartOp.refName="xor";
    }

    //reverse
    if(data.restartOp.operatorRef=="reverse$")
    {
        data.restartOp.usedIdName="Reverse";
        data.restartOp.refName="reverse";
    }

    //Concatenation
    if(data.restartOp.operatorRef=="$@$")
    {
        data.restartOp.usedIdName="Concatenation";
        data.restartOp.refName="@";
    }

    //Times
    if(data.restartOp.operatorRef=="$times$")
    {
        data.restartOp.usedIdName="Times";
        data.restartOp.refName="times";
    }

    //land
    if(data.restartOp.operatorRef=="$land$")
    {
        data.restartOp.usedIdName="land";
        data.restartOp.refName="land";
    }

    //lor
    if(data.restartOp.operatorRef=="$lor$")
    {
        data.restartOp.usedIdName="lor";
        data.restartOp.refName="lor";
    }

    //lxor
    if(data.restartOp.operatorRef=="$lxor$")
    {
        data.restartOp.usedIdName="lxor";
        data.restartOp.refName="lxor";
    }

    //lnot
    if(data.restartOp.operatorRef=="lnot$")
    {
        data.restartOp.usedIdName="lnot";
        data.restartOp.refName="lnot";
    }

    //lsl
    if(data.restartOp.operatorRef=="$lsl$")
    {
        data.restartOp.usedIdName="lsl";
        data.restartOp.refName="lsl";
    }

    //lsr
    if(data.restartOp.operatorRef=="$lsr$")
    {
        data.restartOp.usedIdName="lsr";
        data.restartOp.refName="lsr";
    }

    //自定义操作符
    if(data.restartOp.isRef==true)
    {
        data.restartOp.usedIdName=data.restartOp.operatorRef;
        data.restartOp.refName=data.restartOp.operatorRef;
    }

    int hgap=data.width/2;
    int lgap=data.height/(data.restartOp.calls.size()+1);
    int rgap=data.height/(data.lefts.size()+1);

    portCoordinate ifport;
    ifport.type="if";
    ifport.x=data.x+hgap-5;
    ifport.y=data.y;
    data.ifList.append(ifport);

    for(int i=0;i<data.restartOp.calls.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<data.lefts.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+rgap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.ifList);
    data.rightList.append(data.inList);
}

void OperatorImporter::parseIteratorOpPorts(Equation &data)
{
    data.eleType="ELETYPE_HIGHER";
    data.opeName=data.iteratorOp.iteratorType;
    data.text=data.iteratorOp.size.value;

    //Unary Minus取反运算
    if(data.iteratorOp.operatorRef=="-$")
    {
        data.iteratorOp.usedIdName="-";
        data.iteratorOp.refName="-";
    }

    //Not非运算
    if(data.iteratorOp.operatorRef=="not$")
    {
        data.iteratorOp.usedIdName="not";
        data.iteratorOp.refName="not";
    }

    //Convert To Integer强制转换为整数运算
    if(data.iteratorOp.operatorRef=="int$")
    {
        data.iteratorOp.usedIdName="INT";
        data.iteratorOp.refName="int";
    }

    //Convert To Real强制转换换浮点数运算
    if(data.iteratorOp.operatorRef=="real$")
    {
        data.iteratorOp.usedIdName="REAL";
        data.iteratorOp.refName="real";
    }

    //Minus 减法运算
    if(data.iteratorOp.operatorRef=="$-$")
    {
        data.iteratorOp.usedIdName="+-";
        data.iteratorOp.refName="-";
    }

    //Polymorphic Division 除法运算（输出值为浮点数）
    if(data.iteratorOp.operatorRef=="$/$")
    {
        data.iteratorOp.usedIdName="pdiv";
        data.iteratorOp.refName="pdiv";
    }

    //Integer Division 除法运算（输出值为整数）
    if(data.iteratorOp.operatorRef=="$div$")
    {
        data.iteratorOp.usedIdName="div";
        data.iteratorOp.refName="div";
    }

    //Modulo 求余运算
    if(data.iteratorOp.operatorRef=="$mod$")
    {
        data.iteratorOp.usedIdName="MOD";
        data.iteratorOp.refName="mod";
    }

    //Strictly Less Than  <
    if(data.iteratorOp.operatorRef=="$<$")
    {
        data.iteratorOp.usedIdName="<";
        data.iteratorOp.refName="<";
    }

    //Less Than Or Equal   <=
    if(data.iteratorOp.operatorRef=="$<=$")
    {
        data.iteratorOp.usedIdName="<=";
        data.iteratorOp.refName="<=";
    }

    //Strictly Greater Than  >
    if(data.iteratorOp.operatorRef=="$>$")
    {
        data.iteratorOp.usedIdName=">";
        data.iteratorOp.refName=">";
    }

    //Greater Than Or Equal   >=
    if(data.iteratorOp.operatorRef=="$>=$")
    {
        data.iteratorOp.usedIdName=">=";
        data.iteratorOp.refName=">=";
    }

    //Different  !=
    if(data.iteratorOp.operatorRef=="$<>$")
    {
        data.iteratorOp.usedIdName="<>";
        data.iteratorOp.refName="<>";
    }

    //Equal    ==
    if(data.iteratorOp.operatorRef=="$=$")
    {
        data.iteratorOp.usedIdName="=";
        data.iteratorOp.refName="=";
    }

    //Plus加法运算
    if(data.iteratorOp.operatorRef=="$+$")
    {
        data.iteratorOp.usedIdName="++";
        data.iteratorOp.refName="+";
    }

    //Multiplication乘法运算
    if(data.iteratorOp.operatorRef=="$*$")
    {
        data.iteratorOp.usedIdName="*";
        data.iteratorOp.refName="*";
    }

    //And 与运算
    if(data.iteratorOp.operatorRef=="$and$")
    {
        data.iteratorOp.usedIdName="and";
        data.iteratorOp.refName="and";
    }

    //Or 或运算
    if(data.iteratorOp.operatorRef=="$or$")
    {
        data.iteratorOp.usedIdName="or";
        data.iteratorOp.refName="or";
    }

    //Exclusive Or异或运算
    if(data.iteratorOp.operatorRef=="$xor$")
    {
        data.iteratorOp.usedIdName="xor";
        data.iteratorOp.refName="xor";
    }

    //reverse
    if(data.iteratorOp.operatorRef=="reverse$")
    {
        data.iteratorOp.usedIdName="Reverse";
        data.iteratorOp.refName="reverse";
    }

    //Concatenation
    if(data.iteratorOp.operatorRef=="$@$")
    {
        data.iteratorOp.usedIdName="Concatenation";
        data.iteratorOp.refName="@";
    }

    //Times
    if(data.iteratorOp.operatorRef=="$times$")
    {
        data.iteratorOp.usedIdName="Times";
        data.iteratorOp.refName="times";
    }

    //land
    if(data.iteratorOp.operatorRef=="$land$")
    {
        data.iteratorOp.usedIdName="land";
        data.iteratorOp.refName="land";
    }

    //lor
    if(data.iteratorOp.operatorRef=="$lor$")
    {
        data.iteratorOp.usedIdName="lor";
        data.iteratorOp.refName="lor";
    }

    //lxor
    if(data.iteratorOp.operatorRef=="$lxor$")
    {
        data.iteratorOp.usedIdName="lxor";
        data.iteratorOp.refName="lxor";
    }

    //lnot
    if(data.iteratorOp.operatorRef=="lnot$")
    {
        data.iteratorOp.usedIdName="lnot";
        data.iteratorOp.refName="lnot";
    }

    //lsl
    if(data.iteratorOp.operatorRef=="$lsl$")
    {
        data.iteratorOp.usedIdName="lsl";
        data.iteratorOp.refName="lsl";
    }

    //lsr
    if(data.iteratorOp.operatorRef=="$lsr$")
    {
        data.iteratorOp.usedIdName="lsr";
        data.iteratorOp.refName="lsr";
    }

    //自定义操作符
    if(data.iteratorOp.isRef==true)
    {
        data.iteratorOp.usedIdName=data.iteratorOp.operatorRef;
        data.iteratorOp.refName=data.iteratorOp.operatorRef;
    }

    int lgap=data.height/(data.iteratorOp.calls.size()+1);
    int rgap=data.height/(data.lefts.size()+1);

    for(int i=0;i<data.iteratorOp.calls.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<data.lefts.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+rgap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.inList);
}

void OperatorImporter::parsePartialIteratorOpPorts(Equation &data)
{
    data.eleType="ELETYPE_HIGHER";
    data.opeName=data.partialIteratorOp.partialIteratorType;
    data.text=data.partialIteratorOp.size.value;

    //Unary Minus取反运算
    if(data.partialIteratorOp.operatorRef=="-$")
    {
        data.partialIteratorOp.usedIdName="-";
        data.partialIteratorOp.refName="-";
    }

    //Not非运算
    if(data.partialIteratorOp.operatorRef=="not$")
    {
        data.partialIteratorOp.usedIdName="not";
        data.partialIteratorOp.refName="not";
    }

    //Convert To Integer强制转换为整数运算
    if(data.partialIteratorOp.operatorRef=="int$")
    {
        data.partialIteratorOp.usedIdName="INT";
        data.partialIteratorOp.refName="int";
    }

    //Convert To Real强制转换换浮点数运算
    if(data.partialIteratorOp.operatorRef=="real$")
    {
        data.partialIteratorOp.usedIdName="REAL";
        data.partialIteratorOp.refName="real";
    }

    //Minus 减法运算
    if(data.partialIteratorOp.operatorRef=="$-$")
    {
        data.partialIteratorOp.usedIdName="+-";
        data.partialIteratorOp.refName="-";
    }

    //Polymorphic Division 除法运算（输出值为浮点数）
    if(data.partialIteratorOp.operatorRef=="$/$")
    {
        data.partialIteratorOp.usedIdName="pdiv";
        data.partialIteratorOp.refName="pdiv";
    }

    //Integer Division 除法运算（输出值为整数）
    if(data.partialIteratorOp.operatorRef=="$div$")
    {
        data.partialIteratorOp.usedIdName="div";
        data.partialIteratorOp.refName="div";
    }

    //Modulo 求余运算
    if(data.partialIteratorOp.operatorRef=="$mod$")
    {
        data.partialIteratorOp.usedIdName="MOD";
        data.partialIteratorOp.refName="mod";
    }

    //Strictly Less Than  <
    if(data.partialIteratorOp.operatorRef=="$<$")
    {
        data.partialIteratorOp.usedIdName="<";
        data.partialIteratorOp.refName="<";
    }

    //Less Than Or Equal   <=
    if(data.partialIteratorOp.operatorRef=="$<=$")
    {
        data.partialIteratorOp.usedIdName="<=";
        data.partialIteratorOp.refName="<=";
    }

    //Strictly Greater Than  >
    if(data.partialIteratorOp.operatorRef=="$>$")
    {
        data.partialIteratorOp.usedIdName=">";
        data.partialIteratorOp.refName=">";
    }

    //Greater Than Or Equal   >=
    if(data.partialIteratorOp.operatorRef=="$>=$")
    {
        data.partialIteratorOp.usedIdName=">=";
        data.partialIteratorOp.refName=">=";
    }

    //Different  !=
    if(data.partialIteratorOp.operatorRef=="$<>$")
    {
        data.partialIteratorOp.usedIdName="<>";
        data.partialIteratorOp.refName="<>";
    }

    //Equal    ==
    if(data.partialIteratorOp.operatorRef=="$=$")
    {
        data.partialIteratorOp.usedIdName="=";
        data.partialIteratorOp.refName="=";
    }

    //Plus加法运算
    if(data.partialIteratorOp.operatorRef=="$+$")
    {
        data.partialIteratorOp.usedIdName="++";
        data.partialIteratorOp.refName="+";
    }

    //Multiplication乘法运算
    if(data.partialIteratorOp.operatorRef=="$*$")
    {
        data.partialIteratorOp.usedIdName="*";
        data.partialIteratorOp.refName="*";
    }

    //And 与运算
    if(data.partialIteratorOp.operatorRef=="$and$")
    {
        data.partialIteratorOp.usedIdName="and";
        data.partialIteratorOp.refName="and";
    }

    //Or 或运算
    if(data.partialIteratorOp.operatorRef=="$or$")
    {
        data.partialIteratorOp.usedIdName="or";
        data.partialIteratorOp.refName="or";
    }

    //Exclusive Or异或运算
    if(data.partialIteratorOp.operatorRef=="$xor$")
    {
        data.partialIteratorOp.usedIdName="xor";
        data.partialIteratorOp.refName="xor";
    }

    //reverse
    if(data.partialIteratorOp.operatorRef=="reverse$")
    {
        data.partialIteratorOp.usedIdName="Reverse";
        data.partialIteratorOp.refName="reverse";
    }

    //Concatenation
    if(data.partialIteratorOp.operatorRef=="$@$")
    {
        data.partialIteratorOp.usedIdName="Concatenation";
        data.partialIteratorOp.refName="@";
    }

    //Times
    if(data.partialIteratorOp.operatorRef=="$times$")
    {
        data.partialIteratorOp.usedIdName="Times";
        data.partialIteratorOp.refName="times";
    }

    //land
    if(data.partialIteratorOp.operatorRef=="$land$")
    {
        data.partialIteratorOp.usedIdName="land";
        data.partialIteratorOp.refName="land";
    }

    //lor
    if(data.partialIteratorOp.operatorRef=="$lor$")
    {
        data.partialIteratorOp.usedIdName="lor";
        data.partialIteratorOp.refName="lor";
    }

    //lxor
    if(data.partialIteratorOp.operatorRef=="$lxor$")
    {
        data.partialIteratorOp.usedIdName="lxor";
        data.partialIteratorOp.refName="lxor";
    }

    //lnot
    if(data.partialIteratorOp.operatorRef=="lnot$")
    {
        data.partialIteratorOp.usedIdName="lnot";
        data.partialIteratorOp.refName="lnot";
    }

    //lsl
    if(data.partialIteratorOp.operatorRef=="$lsl$")
    {
        data.partialIteratorOp.usedIdName="lsl";
        data.partialIteratorOp.refName="lsl";
    }

    //lsr
    if(data.partialIteratorOp.operatorRef=="$lsr$")
    {
        data.partialIteratorOp.usedIdName="lsr";
        data.partialIteratorOp.refName="lsr";
    }

    //自定义操作符
    if(data.partialIteratorOp.isRef==true)
    {
        data.partialIteratorOp.usedIdName=data.partialIteratorOp.operatorRef;
        data.partialIteratorOp.refName=data.partialIteratorOp.operatorRef;
    }

    int hgap=data.width/2;
    int lgap=data.height/(data.partialIteratorOp.calls.size()+1);
    int rgap=data.height/(data.lefts.size()+1);
    int zgap=data.width/(data.partialIteratorOp.defaultValue.size()+1);

    portCoordinate ifport;
    ifport.type="if";
    ifport.x=data.x+hgap-5;
    ifport.y=data.y;
    data.ifList.append(ifport);

    for(int i=0;i<data.partialIteratorOp.calls.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<data.lefts.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+rgap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.ifList);
    data.rightList.append(data.inList);

    if(data.partialIteratorOp.hasDefault==true)
    {
        for(int i=0;i<data.partialIteratorOp.defaultValue.size();i++)
        {
            portCoordinate paraport;
            paraport.type="para";
            paraport.paraValue=data.partialIteratorOp.defaultValue.at(i).value;

            paraport.x=data.x+zgap*(i+1)-5;
            paraport.y=data.y+data.height;
            data.paraList.append(paraport);
        }

        data.rightList.append(data.paraList);
    }

}

void OperatorImporter::parseOpCallPorts(Equation &data)
{
    data.eleType="ELETYPE_CUST_OPE";
    data.opeName=data.opCall.operatorRef;

    if(data.opeName.contains("::"))
    {
        QStringList list=data.opeName.split("::");

        data.opeName=list.at(list.size()-1);
    }

    data.text="";

    //目前只支持无参数和if的操作符引用
    int lgap=data.height/(data.opCall.calls.size()+1);
    int rgap=data.height/(data.lefts.size()+1);

    for(int i=0;i<data.opCall.calls.size();i++)
    {
        portCoordinate inport;
        inport.type="in";
        inport.x=data.x;
        inport.y=data.y+lgap*(i+1)-5;
        data.inList.append(inport);
    }

    for(int i=0;i<data.lefts.size();i++)
    {
        portCoordinate outport;
        outport.type="out";
        outport.x=data.x+data.width;
        outport.y=data.y+rgap*(i+1)-5;
        data.outList.append(outport);
    }

    data.rightList.append(data.inList);
}

void OperatorImporter::saveOperatorFile_old(const QString &redaceProjectPath,const QString &scadeProjectName,const QString &operatorFileName,OperatorData &datas)
{
    QString filePath=redaceProjectPath+"/"+scadeProjectName+"/"+operatorFileName;
    QFile file(filePath);
    QFileInfo fileInfo=QFileInfo(filePath);

    if(!file.open(QFile::WriteOnly|QFile::Truncate))
        return;

    QXmlStreamWriter writer(&file);

    writer.setAutoFormatting(true);
    writer.setAutoFormattingIndent(2);

    //写入StartDocument
    writer.writeStartDocument();

    //写File节点
    writer.writeStartElement("File");
    writer.writeAttribute("Type","Operator");

    //declarations
    writer.writeStartElement("declarations");

    //Operator
    writer.writeStartElement("Operator");
    writer.writeAttribute("kind",datas.kind);

    if(datas.isImported==true)
        writer.writeAttribute("external","imported");

    writer.writeAttribute("name",datas.operatorName);

    //operator_property
    writer.writeStartElement("operator_property");
    writer.writeAttribute("description",datas.comment);
    writer.writeAttribute("subFolderName","");
    writer.writeAttribute("isInSubFolder","False");

    if(datas.isImported==false)
    {
        writer.writeAttribute("isImportOpe","false");
        writer.writeAttribute("cFilePath","");
        writer.writeAttribute("hFilePath","");
    }
    else
    {
        writer.writeAttribute("isImportOpe","true");
        writer.writeAttribute("cFilePath",datas.cFilePath);
        writer.writeAttribute("hFilePath","");
    }


    writer.writeAttribute("stylePath","");
    writer.writeEndElement();//结束operator_property

    //inputs
    bool hasInput=false;
    for(int i=0;i<datas.variables.size();i++)
    {
        if(datas.variables.at(i).type=="input")
        {
            hasInput=true;
        }
    }
    if(hasInput==true)
    {
        writer.writeStartElement("inputs");
        for(int i=0;i<datas.variables.size();i++)
        {
            if(datas.variables.at(i).type=="input")
            {
                saveVariable(writer,datas.variables.at(i));
            }
        }

        writer.writeEndElement();
    }


    //outputs
    bool hasOutput=false;
    for(int i=0;i<datas.variables.size();i++)
    {
        if(datas.variables.at(i).type=="output")
        {
            hasOutput=true;
        }
    }
    if(hasOutput==true)
    {
        writer.writeStartElement("outputs");
        for(int i=0;i<datas.variables.size();i++)
        {
            if(datas.variables.at(i).type=="output")
            {
                saveVariable(writer,datas.variables.at(i));
            }
        }

        writer.writeEndElement();
    }

    //locals
    bool hasLocal=false;
    for(int i=0;i<datas.variables.size();i++)
    {
        if(datas.variables.at(i).type=="local")
        {
            hasLocal=true;
        }
    }
    if(hasLocal==true)
    {
        writer.writeStartElement("locals");
        for(int i=0;i<datas.variables.size();i++)
        {
            if(datas.variables.at(i).type=="local")
            {
                saveVariable(writer,datas.variables.at(i));
            }
        }

        writer.writeEndElement();
    }

    //data
    if(!datas.equations.isEmpty())
    {
        writer.writeStartElement("data");
        for(int i=0;i<datas.equations.size();i++)
        {
            saveEquation(writer,datas.equations.at(i));
        }
        writer.writeEndElement();
    }

    //oid
    writer.writeStartElement("oid");
    writer.writeAttribute("value",datas.scadeOid);
    writer.writeEndElement();//结束oid

    //diagrams
    if(!datas.diagrams.isEmpty())
    {
        writer.writeStartElement("diagrams");
        for(int i=0;i<datas.diagrams.size();i++)
        {
            writer.writeStartElement("NetDiagram");
            writer.writeAttribute("name",datas.diagrams.at(i).name);
            writer.writeAttribute("landscape",datas.diagrams.at(i).landscape);
            writer.writeAttribute("oid",datas.diagrams.at(i).redaceOid);
            writer.writeAttribute("EleIDIndex","");
            writer.writeAttribute("OutPortIndex","");
            writer.writeAttribute("ProjectName","");
            writer.writeAttribute("DiagramName","");
            writer.writeAttribute("DiagramId","");
            writer.writeAttribute("Description","");
            writer.writeAttribute("DiagramNum","");
            writer.writeAttribute("DiagramVersion","");
            writer.writeAttribute("DesignPersonName","");
            writer.writeAttribute("DesignTime","");
            writer.writeAttribute("CheckPersonName","");
            writer.writeAttribute("CheckTime","");
            writer.writeAttribute("DeterminePersonName","");
            writer.writeAttribute("DetermineTime","");
            writer.writeAttribute("ApprovePersonName","");
            writer.writeAttribute("ApproveTime","");
            writer.writeAttribute("FDDiagram","False");
            writer.writeAttribute("BackgroundImageWidth","0");
            writer.writeAttribute("BackgroundImageHeight","0");
            writer.writeAttribute("BackgroundImageFileName","");

            writer.writeEndElement();
        }
        writer.writeEndElement();
    }


    writer.writeEndElement();//结束data

    writer.writeEndElement();//结束Operator

    writer.writeEndElement();//结束declarations

    writer.writeEndElement();//结束File

    writer.writeEndDocument();

    file.close();

}

void OperatorImporter::saveDiagramFile(const QString &filePath,OperatorData &datas)
{
    QString pousDirName=filePath+"/"+"POUs";//POUs文件夹
    QDir poudir(pousDirName);
    if(!poudir.exists())
        poudir.mkdir(pousDirName);//创建POUs文件夹

    //创建操作符文件夹
    QString operatorDir=pousDirName+"/"+datas.operatorName;
    QDir opedir(operatorDir);
    if(!opedir.exists())
        opedir.mkdir(operatorDir);

    //    int EleID=0;

    for(int i=0;i<datas.diagrams.size();i++)
    {
        int eleIDIndex=0;
        int outPortIndex=1;

        QFile file(operatorDir+"/"+datas.diagrams.at(i).name);
        QFileInfo fileInfo=QFileInfo(operatorDir+"/"+datas.diagrams.at(i).name);

        if(!file.open(QFile::WriteOnly|QFile::Truncate))
            return;

        QXmlStreamWriter writer(&file);

        //presentationElements
        writer.writeStartElement("presentationElements");

        //生成图元
        saveEquationGE(writer,datas.diagrams.at(i).equations,eleIDIndex,outPortIndex);

        //生成连接线
        saveLineGE(writer,datas.diagrams.at(i),eleIDIndex);

        writer.writeEndElement();


        file.close();

        //校正操作符文件中的算法页面的EleIDIndex和OutPortIndex值
        QFile opeFile(filePath+"/"+datas.operatorFileName);

        QString strAll;
        QStringList strList;

        if(opeFile.open(QIODevice::ReadOnly|QIODevice::Text))
        {
            QTextStream stream(&opeFile);
            stream.setCodec("UTF-8");
            strAll=stream.readAll();
        }

        opeFile.close();

        if(opeFile.open(QIODevice::WriteOnly|QIODevice::Text))
        {
            QTextStream stream(&opeFile);
            stream.setCodec("utf-8");
            strList=strAll.split("\n");

            for(int j=0;j<strList.size();j++)
            {
                if(strList.at(j).contains("name=\""+datas.diagrams.at(i).name+"\""))
                {
                    strList[j].replace("EleIDIndex=\"\"","EleIDIndex=\""+QString("%1").arg(eleIDIndex)+"\"");
                    strList[j].replace("OutPortIndex=\"\"","OutPortIndex=\""+QString("%1").arg(outPortIndex)+"\"");
                }

                stream<<strList.at(j)<<endl;
            }

        }

        opeFile.close();
    }

    for(auto stateOid:datas.stmModel.states().keys())
    {
        State state=*datas.stmModel.getState(stateOid);

        if(state.pouList.isEmpty())
        {
            continue;
        }

        //创建操作符文件夹
        QString stateDir=pousDirName+"/"+state.hierarchy;
        QDir statedir(stateDir);
        if(!statedir.exists())
            statedir.mkdir(stateDir);

        int eleIDIndex=0;
        int outPortIndex=1;

        for(auto pou:state.pouList)
        {
            Diagram dia=pou.dia;

            QFile file(stateDir+"/"+pou.name);
            QFileInfo fileInfo=QFileInfo(stateDir+"/"+pou.name);

            if(!file.open(QFile::WriteOnly|QFile::Truncate))
                return;

            QXmlStreamWriter writer(&file);

            //presentationElements
            writer.writeStartElement("presentationElements");

            //生成图元
            saveEquationGE(writer,dia.equations,eleIDIndex,outPortIndex);

            //生成连接线
            saveLineGE(writer,dia,eleIDIndex);

            writer.writeEndElement();

            file.close();
        }
    }

    for(auto action:datas.blockModel.actionMap)
    {
        if(action.pouList.isEmpty())
        {
            continue;
        }

        int eleIDIndex=0;
        int outPortIndex=1;

        for(auto pou:action.pouList)
        {
            Diagram dia=pou.dia;

            QFile file(operatorDir+"/"+pou.name);
            QFileInfo fileInfo=QFileInfo(operatorDir+"/"+pou.name);

            if(!file.open(QFile::WriteOnly|QFile::Truncate))
                return;

            QXmlStreamWriter writer(&file);

            //presentationElements
            writer.writeStartElement("presentationElements");

            //生成图元
            saveEquationGE(writer,dia.equations,eleIDIndex,outPortIndex);

            //生成连接线
            saveLineGE(writer,dia,eleIDIndex);

            writer.writeEndElement();

            file.close();
        }

    }
}

void OperatorImporter::saveEquationGE(QXmlStreamWriter &writer,const QList<Equation>& equations,int &eleIDindex,int &outPortIndex)
{
    for(int j=0;j<equations.size();j++)
    {
        Equation equation=equations.at(j);

        if(equation.id>=eleIDindex)
        {
            eleIDindex=equation.id+1;
        }

        writer.writeStartElement("EquationGE");
        writer.writeAttribute("EleID",QString("%1").arg(equation.id));//EleID
        writer.writeAttribute("presentable",equation.redaceId);//oid

        writer.writeAttribute("EleType",equation.eleType);
        writer.writeAttribute("OpeName",equation.opeName);
        if(equation.operatorType=="OpCall")
        {
            writer.writeAttribute("CustomOpeSerialNumber",QUuid::createUuid().toString(QUuid::WithoutBraces));
        }

        //消除立即数中用到的常量含::的包路径
        if(equation.eleType=="ELETYPE_IMMEDIATE"&&equation.text.contains("::"))
        {
            // 分割字符串，跳过空部分
            QStringList parts = equation.text.split(' ', QString::SkipEmptyParts);
            QStringList processedParts;

            for (const QString &part : parts) {
                // 查找最后一个 "::" 的位置
                int lastIndex = part.lastIndexOf("::");
                QString newPart = part;

                if (lastIndex != -1) {
                    newPart = part.mid(lastIndex + 2); // 截取最后一个 "::" 之后的内容
                }

                // 过滤空字符串
                if (!newPart.isEmpty()) {
                    processedParts.append(newPart);
                }
            }

            // 重新用空格拼接处理后的子字符串
            equation.text=processedParts.join(" ");

            writer.writeAttribute("Text",equation.text);
        }
        else
        {
            writer.writeAttribute("Text",equation.text);
        }

        writer.writeAttribute("Instance","");

        if(equation.operatorType!="IteratorOp"&&equation.operatorType!="PartialIteratorOp"&&equation.operatorType!="ActivateOp"&&equation.operatorType!="RestartOp")
        {
            writer.writeAttribute("UsedIdName","");
            writer.writeAttribute("RefName","");
        }

        if(equation.operatorType=="ActivateOp")
        {
            writer.writeAttribute("UsedIdName",equation.activateOp.usedIdName);
            writer.writeAttribute("RefName",equation.activateOp.refName);

            if(equation.activateOp.isRef==false)
            {
                writer.writeAttribute("IsRefOpe","False");
            }
            else {
                writer.writeAttribute("IsRefOpe","True");
            }

        }

        if(equation.operatorType=="RestartOp")
        {
            writer.writeAttribute("UsedIdName",equation.restartOp.usedIdName);
            writer.writeAttribute("RefName",equation.restartOp.refName);

            if(equation.restartOp.isRef==false)
            {
                writer.writeAttribute("IsRefOpe","False");
            }
            else {
                writer.writeAttribute("IsRefOpe","True");
            }

        }

        if(equation.operatorType=="IteratorOp")
        {
            writer.writeAttribute("UsedIdName",equation.iteratorOp.usedIdName);
            writer.writeAttribute("RefName",equation.iteratorOp.refName);

            if(equation.iteratorOp.isRef==false)
            {
                writer.writeAttribute("IsRefOpe","False");
            }
            else {
                writer.writeAttribute("IsRefOpe","True");
            }

        }

        if(equation.operatorType=="PartialIteratorOp")
        {
            writer.writeAttribute("UsedIdName",equation.partialIteratorOp.usedIdName);
            writer.writeAttribute("RefName",equation.partialIteratorOp.refName);

            if(equation.partialIteratorOp.isRef==false)
            {
                writer.writeAttribute("IsRefOpe","False");
            }
            else {
                writer.writeAttribute("IsRefOpe","True");
            }

        }

        writer.writeAttribute("rcMode","");
        writer.writeAttribute("styleName","");
        writer.writeAttribute("Angle","0");
        writer.writeAttribute("FDOid","");
        writer.writeAttribute("ContainPageName","False");

        //comment
        writer.writeStartElement("comment");
        writer.writeStartElement("Comment");
        writer.writeAttribute("valueStr",equation.comment);
        writer.writeEndElement();
        writer.writeEndElement();

        //portNum
        writer.writeStartElement("portNum");
        writer.writeStartElement("Number");
        writer.writeAttribute("IfNum",QString("%1").arg(equation.ifList.size()));
        writer.writeAttribute("InNum",QString("%1").arg(equation.inList.size()));
        if(equation.operatorType=="DataStructOp"||equation.operatorType=="CaseOp")
        {
            writer.writeAttribute("ParaNum","0");
        }
        else {
            writer.writeAttribute("ParaNum",QString("%1").arg(equation.paraList.size()));
        }

        writer.writeAttribute("OutNum",QString("%1").arg(equation.outList.size()));
        writer.writeEndElement();
        writer.writeEndElement();

        //position
        writer.writeStartElement("position");
        writer.writeStartElement("Point");
        writer.writeAttribute("x",QString("%1").arg(equation.x));
        writer.writeAttribute("y",QString("%1").arg(equation.y));
        writer.writeEndElement();
        writer.writeEndElement();

        //size
        writer.writeStartElement("size");
        writer.writeStartElement("Size");
        writer.writeAttribute("width",QString("%1").arg(equation.width));
        writer.writeAttribute("height",QString("%1").arg(equation.height));
        writer.writeEndElement();
        writer.writeEndElement();


        //ifPort
        if(!equation.ifList.isEmpty())
        {
            writer.writeStartElement("ifPort");
            writer.writeAttribute("eleID",QString("%1").arg(equation.id));

            writer.writeAttribute("ifLinkId",QString("%1").arg(equation.rightList.at(0).linkLine.id+equation.rightList.at(0).linkLine.lineLengthList.size()*2-1));

            writer.writeEndElement();
        }

        //linkEleID        
        if(!equation.inList.isEmpty())
        {
            writer.writeStartElement("linkEleID");
            writer.writeAttribute("eleID",QString("%1").arg(equation.id));
            for(int k=0;k<equation.inList.size();k++)
            {
                if(!equation.rightList.at(equation.ifList.size()+k).linkLine.rightIndex.isEmpty())
                {
                    writer.writeStartElement("PortID");
                    writer.writeAttribute("linkIndex",QString("%1").arg(k));
                    writer.writeAttribute("linkPortIndex","0");
                    writer.writeAttribute("linkId",QString("%1").arg(equation.rightList.at(equation.ifList.size()+k).linkLine.id+equation.rightList.at(equation.ifList.size()+k).linkLine.lineLengthList.size()*2));

                    Equation leftEquation;
                    for(int n=0;n<m_operator.equations.size();n++)
                    {
                        if(m_operator.equations.at(n).oid==equation.rightList.at(equation.ifList.size()+k).linkLine.leftEquationOid)
                            leftEquation=m_operator.equations.at(n);
                    }

                    for(auto state:m_operator.stmModel.states().values())
                    {
                        for(auto eq:state.equations)
                        {
                            if(eq.oid==equation.rightList.at(equation.ifList.size()+k).linkLine.leftEquationOid)
                                leftEquation=eq;
                        }
                    }

                    for(auto action:m_operator.blockModel.actionMap)
                    {
                        for(auto eq:action.equations)
                        {
                            if(eq.oid==equation.rightList.at(equation.ifList.size()+k).linkLine.leftEquationOid)
                                leftEquation=eq;
                        }
                    }

                    QString portDataType;

                    for(int n=0;n<m_operator.variables.size();n++)
                    {

                        if(m_operator.variables.at(n).name==leftEquation.lefts.at(equation.rightList.at(equation.ifList.size()+k).linkLine.leftIndex.toInt()-1))
                            portDataType=m_operator.variables.at(n).dataType;
                    }

                    for(auto state:m_operator.stmModel.states().values())
                    {
                        for(auto var:state.variables)
                        {
                            if(var.name==leftEquation.lefts.at(equation.rightList.at(equation.ifList.size()+k).linkLine.leftIndex.toInt()-1))
                                portDataType=var.dataType;
                        }
                    }

                    for(auto action:m_operator.blockModel.actionMap)
                    {
                        for(auto var:action.variables)
                        {
                            if(var.name==leftEquation.lefts.at(equation.rightList.at(equation.ifList.size()+k).linkLine.leftIndex.toInt()-1))
                                portDataType=var.dataType;
                        }
                    }

                    //去掉portDataType中的包路径
                    if(portDataType.contains("::"))
                    {
                        int lastIndex = portDataType.lastIndexOf("::");
                        portDataType=(lastIndex == -1) ? portDataType : portDataType.mid(lastIndex + 2);
                    }

                    writer.writeAttribute("portDataType",portDataType);
                    writer.writeEndElement();
                }
            }

            writer.writeEndElement();
        }


        //paraPort
        if(!equation.paraList.isEmpty())
        {
            writer.writeStartElement("paraPort");
            writer.writeAttribute("eleID",QString("%1").arg(equation.id));
            for(int k=0;k<equation.paraList.size();k++)
            {
                writer.writeStartElement("ParaID");
                writer.writeAttribute("paraIndex",QString("%1").arg(k));

                //paraLinkId、value
                if(!equation.rightList.at(equation.ifList.size()+equation.inList.size()+k).linkLine.rightIndex.isEmpty())
                {
                    writer.writeAttribute("parLinkId",QString("%1").arg(equation.rightList.at(equation.ifList.size()+equation.inList.size()+k).linkLine.id+equation.rightList.at(equation.ifList.size()+equation.inList.size()+k).linkLine.lineLengthList.size()*2-1));

                    writer.writeAttribute("value","");
                }
                else
                {
                    QString paraValue=equation.rightList.at(equation.ifList.size()+equation.inList.size()+k).paraValue;

                    //去除操作符参数中的::包结构
                    if(paraValue.contains("::"))
                    {
                        int lastIndex = paraValue.lastIndexOf("::");
                        paraValue=(lastIndex == -1) ? paraValue : paraValue.mid(lastIndex + 2);
                    }

                    writer.writeAttribute("parLinkId","");
                    writer.writeAttribute("value",paraValue);

                }

                writer.writeEndElement();

            }

            writer.writeEndElement();

        }

        //outports
        if(!equation.outList.isEmpty())
        {
            writer.writeStartElement("outports");
            writer.writeAttribute("EleID",QString("%1").arg(equation.id));
            for(int k=0;k<equation.outList.size();k++)
            {
                writer.writeStartElement("outportID");
                writer.writeAttribute("outIndex",QString("%1").arg(k));
                writer.writeAttribute("localVarName",equation.lefts.at(k));
                writer.writeEndElement();

                if(equation.lefts.at(k).mid(2).toInt()>=outPortIndex)
                {
                    outPortIndex=equation.lefts.at(k).mid(2).toInt()+1;
                }
            }

            writer.writeEndElement();
        }


        writer.writeEndElement();

    }

}

void OperatorImporter::saveLineGE(QXmlStreamWriter &writer,const Diagram& diagram,int &eleIDindex)
{
    //连接线
    for(int j=0;j<diagram.lineList.size();j++)
    {
        Line line=diagram.lineList.at(j);
        //        line.id=EleID;
        //        datas.diagrams[i].lineList[j].id=EleID;

        int eleID=line.id;

        //连接线左右图元
        Equation leftEquation;
        Equation rightEquation;

        for(int k=0;k<diagram.equations.size();k++)
        {
            if(diagram.equations.at(k).oid==line.leftEquationOid)
                leftEquation=diagram.equations.at(k);

            if(diagram.equations.at(k).oid==line.rightEquationOid)
                rightEquation=diagram.equations.at(k);
        }

        //连接线起点
        int x=line.beginX;
        int y=line.beginY;

        for(int k=0;k<line.lineLengthList.size();k++)
        {
            LineLength lineLength=line.lineLengthList.at(k);

            for(int m=0;m<2;m++)
            {
                writer.writeStartElement("EquationGE");
                writer.writeAttribute("EleID",QString("%1").arg(eleID));//EleID
                writer.writeAttribute("presentable",QUuid::createUuid().toString(QUuid::WithoutBraces));//oid

                QString eleType="ELETYPE_LINE";
                //                QString ifNum="0";
                //                QString inNum="1";
                //                QString paraNum="0";
                //                QString outNum="1";

                writer.writeAttribute("EleType",eleType);
                writer.writeAttribute("OpeName","");
                writer.writeAttribute("Text","");
                writer.writeAttribute("Instance","");
                writer.writeAttribute("UsedIdName","");
                writer.writeAttribute("RefName","");

                //rcmode
                QString rcMode;
                if(m==0)
                {
                    if(lineLength.hLength>=0)
                        rcMode="HLINE";
                    else {
                        rcMode="HLINE_REV";
                    }
                }

                if(m==1)
                {
                    if(lineLength.zLength>=0)
                        rcMode="ZLINE";
                    else {
                        rcMode="ZLINE_REV";
                    }
                }

                writer.writeAttribute("rcMode",rcMode);
                writer.writeAttribute("Pattern","0");
                writer.writeAttribute("styleName","");
                writer.writeAttribute("Angle","0");
                writer.writeAttribute("FDOid","");
                writer.writeAttribute("ContainPageName","False");

                //comment
                writer.writeStartElement("comment");
                writer.writeStartElement("Comment");
                writer.writeAttribute("valueStr","");
                writer.writeEndElement();
                writer.writeEndElement();

                //portNum
                writer.writeStartElement("portNum");
                writer.writeStartElement("Number");
                writer.writeAttribute("IfNum","0");
                writer.writeAttribute("InNum","1");
                writer.writeAttribute("ParaNum","0");
                writer.writeAttribute("OutNum","1");
                writer.writeEndElement();
                writer.writeEndElement();

                //position
                writer.writeStartElement("position");
                writer.writeStartElement("Point");


                if(m==0)
                {
                    writer.writeAttribute("x",QString("%1").arg(x));
                    writer.writeAttribute("y",QString("%1").arg(y));

                    x=x+lineLength.hLength-5;
                    y=y+5;
                }

                if(m==1)
                {
                    writer.writeAttribute("x",QString("%1").arg(x));
                    writer.writeAttribute("y",QString("%1").arg(y));

                    x=x+5;
                    y=y+lineLength.zLength-5;
                }

                writer.writeEndElement();
                writer.writeEndElement();

                //size
                writer.writeStartElement("size");
                writer.writeStartElement("Size");

                if(m==0)
                {
                    writer.writeAttribute("width",QString("%1").arg(lineLength.hLength));
                    writer.writeAttribute("height",QString("%1").arg(10));
                }

                if(m==1)
                {
                    writer.writeAttribute("width",QString("%1").arg(10));
                    writer.writeAttribute("height",QString("%1").arg(lineLength.zLength));
                }
                writer.writeEndElement();
                writer.writeEndElement();

                //linkEleID
                writer.writeStartElement("linkEleID");
                writer.writeAttribute("eleID",QString("%1").arg(eleID));
                writer.writeStartElement("PortID");
                writer.writeAttribute("linkIndex","0");

                if(k==0&&m==0)
                {
                    writer.writeAttribute("linkPortIndex",QString("%1").arg(line.leftIndex.toInt()-1));
                    writer.writeAttribute("linkId",QString("%1").arg(leftEquation.id));
                }
                else {
                    writer.writeAttribute("linkPortIndex","0");
                    writer.writeAttribute("linkId",QString("%1").arg(eleID-1));
                }

                QString portDataType;
                for(int n=0;n<m_operator.variables.size();n++)
                {
                    if(m_operator.variables.at(n).name==leftEquation.lefts.at(line.leftIndex.toInt()-1))
                        portDataType=m_operator.variables.at(n).dataType;
                }

                //去掉portDataType中的包路径
                if(portDataType.contains("::"))
                {
                    int lastIndex = portDataType.lastIndexOf("::");
                    portDataType=(lastIndex == -1) ? portDataType : portDataType.mid(lastIndex + 2);
                }

                writer.writeAttribute("portDataType",portDataType);
                writer.writeEndElement();
                writer.writeEndElement();

                //outports
                writer.writeStartElement("outports");
                writer.writeAttribute("EleID",QString("%1").arg(eleID));
                writer.writeStartElement("outportID");
                writer.writeAttribute("outIndex","0");
                writer.writeAttribute("localVarName",leftEquation.lefts.at(line.leftIndex.toInt()-1));
                writer.writeEndElement();
                writer.writeEndElement();

                writer.writeEndElement();

                eleID++;

            }



        }

        if(rightEquation.rightList.at(line.rightIndex.toInt()-1).type=="in")
        {
            //最后一个HLINE
            writer.writeStartElement("EquationGE");
            writer.writeAttribute("EleID",QString("%1").arg(eleID));//EleID
            writer.writeAttribute("presentable",QUuid::createUuid().toString(QUuid::WithoutBraces));//oid

            QString eleType="ELETYPE_LINE";

            writer.writeAttribute("EleType",eleType);
            writer.writeAttribute("OpeName","");
            writer.writeAttribute("Text","");
            writer.writeAttribute("Instance","");
            writer.writeAttribute("UsedIdName","");
            writer.writeAttribute("RefName","");

            //rcMode
            QString rcMode;
            if((x+5)<=line.endX)
                rcMode="HLINE";
            else {
                rcMode="HLINE_REV";
            }

            writer.writeAttribute("rcMode",rcMode);
            writer.writeAttribute("Pattern","0");
            writer.writeAttribute("styleName","");
            writer.writeAttribute("Angle","0");
            writer.writeAttribute("FDOid","");
            writer.writeAttribute("ContainPageName","False");

            //comment
            writer.writeStartElement("comment");
            writer.writeStartElement("Comment");
            writer.writeAttribute("valueStr","");
            writer.writeEndElement();
            writer.writeEndElement();

            //portNum
            writer.writeStartElement("portNum");
            writer.writeStartElement("Number");
            writer.writeAttribute("IfNum","0");
            writer.writeAttribute("InNum","1");
            writer.writeAttribute("ParaNum","0");
            writer.writeAttribute("OutNum","1");
            writer.writeEndElement();
            writer.writeEndElement();

            //position
            writer.writeStartElement("position");
            writer.writeStartElement("Point");
            writer.writeAttribute("x",QString("%1").arg(x));
            writer.writeAttribute("y",QString("%1").arg(y));

            writer.writeEndElement();
            writer.writeEndElement();

            //size
            int width=line.endX-x;

            writer.writeStartElement("size");
            writer.writeStartElement("Size");
            writer.writeAttribute("width",QString("%1").arg(width));
            writer.writeAttribute("height",QString("%1").arg(10));

            writer.writeEndElement();
            writer.writeEndElement();

            //linkEleID
            writer.writeStartElement("linkEleID");
            writer.writeAttribute("eleID",QString("%1").arg(eleID));
            writer.writeStartElement("PortID");
            writer.writeAttribute("linkIndex","0");
            writer.writeAttribute("linkPortIndex","0");
            writer.writeAttribute("linkId",QString("%1").arg(eleID-1));
            QString portDataType;
            for(int n=0;n<m_operator.variables.size();n++)
            {
                if(m_operator.variables.at(n).name==leftEquation.lefts.at(line.leftIndex.toInt()-1))
                    portDataType=m_operator.variables.at(n).dataType;
            }

            //去掉portDataType中的包路径
            if(portDataType.contains("::"))
            {
                int lastIndex = portDataType.lastIndexOf("::");
                portDataType=(lastIndex == -1) ? portDataType : portDataType.mid(lastIndex + 2);
            }

            writer.writeAttribute("portDataType",portDataType);
            writer.writeEndElement();
            writer.writeEndElement();

            //outports
            writer.writeStartElement("outports");
            writer.writeAttribute("EleID",QString("%1").arg(eleID));
            writer.writeStartElement("outportID");
            writer.writeAttribute("outIndex","0");
            writer.writeAttribute("localVarName",leftEquation.lefts.at(line.leftIndex.toInt()-1));
            writer.writeEndElement();
            writer.writeEndElement();

            writer.writeEndElement();

            //        EleID++;
        }

        if(eleID>=eleIDindex)
        {
            eleIDindex=eleID+1;
        }

    }
}

void OperatorImporter::saveVariable(QXmlStreamWriter &writer,const Variable &data)
{
    writer.writeStartElement("Variable");
    writer.writeAttribute("name",data.name);

    writer.writeStartElement("type");

    //普通变量
    if(data.isStruct==false&&data.isArray==false)
    {
        writer.writeStartElement("NamedType");
        writer.writeStartElement("type");
        writer.writeStartElement("TypeRef");
        writer.writeAttribute("name",data.dataType);

        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();
    }

    //结构体变量
    if(data.isStruct==true)
    {
        writer.writeStartElement("Struct");
        writer.writeStartElement("fields");

        for(int i=0;i<data.fieldList.size();i++)
        {
            writer.writeStartElement("Field");
            writer.writeAttribute("name",data.fieldList.at(i).name);
            writer.writeStartElement("type");
            writer.writeStartElement("NamedType");
            writer.writeStartElement("type");
            writer.writeStartElement("TypeRef");
            writer.writeAttribute("name",data.fieldList.at(i).type);

            writer.writeEndElement();
            writer.writeEndElement();
            writer.writeEndElement();
            writer.writeEndElement();

            writer.writeStartElement("oid");
            writer.writeAttribute("value",data.fieldList.at(i).oid);
            writer.writeEndElement();
            writer.writeEndElement();
        }

        writer.writeEndElement();
        writer.writeEndElement();
    }

    //数组变量
    if(data.isArray==true)
    {
        writer.writeStartElement("Table");
        writer.writeStartElement("type");
        writer.writeStartElement("NamedType");
        writer.writeStartElement("type");
        writer.writeStartElement("TypeRef");
        writer.writeAttribute("name",data.array.type);

        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();

        writer.writeStartElement("size");

        //数组大小为立即数时
        if(data.array.size.value.contains(QRegExp("^\\d+$")))
        {
            writer.writeStartElement("ConstValue");
            writer.writeAttribute("value",data.array.size.value);
            writer.writeEndElement();
        }
        else
        {
            writer.writeStartElement("IdExpression");
            writer.writeStartElement("path");
            writer.writeStartElement("ConstVarRef");
            writer.writeAttribute("name",data.array.size.value);

            writer.writeEndElement();
            writer.writeEndElement();
            writer.writeEndElement();
        }

        writer.writeEndElement();


        writer.writeEndElement();
    }

    writer.writeEndElement();

    writer.writeStartElement("oid");
    writer.writeAttribute("value",data.id);
    writer.writeEndElement();

    if(!data.comment.isEmpty())
    {
        writer.writeStartElement("pragmas");
        writer.writeStartElement("comment");
        writer.writeAttribute("value",data.comment);

        writer.writeEndElement();
        writer.writeEndElement();
    }

    writer.writeEndElement();
}

void OperatorImporter::saveEquation(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("Equation");
    writer.writeAttribute("oid",data.pageId);

    //lefts
    if(!data.lefts.isEmpty())
    {
        writer.writeStartElement("lefts");
        for (int i=0;i<data.lefts.size();i++)
        {
            writer.writeStartElement("VariableRef");
            writer.writeAttribute("name",data.lefts.at(i));
            writer.writeEndElement();

        }
        writer.writeEndElement();
    }

    //right
    writer.writeStartElement("right");

    //输入变量、输出变量、本地变量、常量、立即数、结束符
    if(data.type=="inputVar"||data.type=="outputVar"||data.type=="localInputVar"||data.type=="localOutputVar"||data.type=="constant"||data.type=="immediate"||data.type=="terminator")
    {

        if(data.type!="immediate")
        {
            saveIdExpression(writer,data.rightVarRef);

        }
        else {
            writer.writeStartElement("ConstValue");
            writer.writeAttribute("value",data.rightVarRef);
            writer.writeEndElement();
        }

    }

    //操作符
    if(data.type=="operator")
    {
        saveOperator(writer,data);
    }

    writer.writeEndElement();//right

    //oid
    writer.writeStartElement("oid");
    writer.writeAttribute("value",data.redaceId);
    writer.writeEndElement();

    //comment
    if(!data.comment.isEmpty())
    {
        writer.writeStartElement("pragmas");
        writer.writeStartElement("comment");
        writer.writeAttribute("value",data.comment);

        writer.writeEndElement();
        writer.writeEndElement();
    }

    writer.writeEndElement();
}

void OperatorImporter::saveOperator(QXmlStreamWriter &writer,const Equation &data)
{
    //一元操作符
    if(data.operatorType=="UnaryOp")
        saveUnaryOp(writer,data);

    //二元操作符
    if(data.operatorType=="BinaryOp")
        saveBinaryOp(writer,data);

    //多元操作符
    if(data.operatorType=="NAryOp")
        saveNAryOp(writer,data);

    //Previous
    if(data.operatorType=="PreOp")
        savePreOp(writer,data);

    //Init
    if(data.operatorType=="InitOp")
        saveInitOp(writer,data);

    //Followed By
    if(data.operatorType=="FbyOp")
        saveFbyOp(writer,data);

    //Projection
    if(data.operatorType=="PrjOp")
        savePrjOp(writer,data);

    //Slice
    if(data.operatorType=="SliceOp")
        saveSliceOp(writer,data);

    //Dynamic Projection
    if(data.operatorType=="PrjDynOp")
        savePrjDynOp(writer,data);

    //DataStructre
    if(data.operatorType=="DataStructOp")
        saveDataStructOp(writer,data);

    //ScalarToVector
    if(data.operatorType=="ScalarToVectorOp")
        saveScalarToVectorOp(writer,data);

    //DataArray
    if(data.operatorType=="DataArrayOp")
        saveDataArrayOp(writer,data);

    //ChgIthOp
    if(data.operatorType=="ChgIthOp")
        saveChgIthOp(writer,data);

    //IfThenElse
    if(data.operatorType=="IfThenElseOp")
        saveIfThenElseOp(writer,data);

    //Case
    if(data.operatorType=="CaseOp")
        saveCaseOp(writer,data);

    //Make
    if(data.operatorType=="MakeOp")
        saveMakeOp(writer,data);

    //Flatten
    if(data.operatorType=="FlattenOp")
        saveFlattenOp(writer,data);

    //Iterator
    if(data.operatorType=="IteratorOp")
        saveIteratorOp(writer,data);

    //PartialIterator
    if(data.operatorType=="PartialIteratorOp")
        savePartialIteratorOp(writer,data);

    //OpCall
    if(data.operatorType=="OpCall")
        saveOpCall(writer,data);
}

void OperatorImporter::saveUnaryOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("UnaryOp");

    if(data.operatorName=="Unary Minus")
        writer.writeAttribute("operator","-");

    if(data.operatorName=="Not")
        writer.writeAttribute("operator","not");

    if(data.operatorName=="Convert To Integer")
        writer.writeAttribute("operator","int");

    if(data.operatorName=="Convert To Real")
        writer.writeAttribute("operator","real");

    writer.writeStartElement("operand");

    saveIdExpression(writer,data.unaryOp.constVarRef);

    writer.writeEndElement();
    writer.writeEndElement();
}

void OperatorImporter::saveBinaryOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("BinaryOp");

    if(data.operatorName=="Minus")
        writer.writeAttribute("operator","-");

    if(data.operatorName=="Polymorphic Division")
        writer.writeAttribute("operator","/");

    if(data.operatorName=="Integer Division")
        writer.writeAttribute("operator","div");

    if(data.operatorName=="Modulo")
        writer.writeAttribute("operator","mod");

    if(data.operatorName=="Strictly Less Than")
        writer.writeAttribute("operator","<");

    if(data.operatorName=="Less Than Or Equal")
        writer.writeAttribute("operator","<=");

    if(data.operatorName=="Strictly Greater Than")
        writer.writeAttribute("operator",">");

    if(data.operatorName=="Greater Than Or Equal")
        writer.writeAttribute("operator",">=");

    if(data.operatorName=="Different")
        writer.writeAttribute("operator","<>");

    if(data.operatorName=="Equal")
        writer.writeAttribute("operator","=");

    writer.writeStartElement("operands");

    saveIdExpression(writer,data.binaryOp.constVarRefs.at(0));
    saveIdExpression(writer,data.binaryOp.constVarRefs.at(1));

    writer.writeEndElement();
    writer.writeEndElement();
}

void OperatorImporter::saveNAryOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("NAryOp");

    if(data.operatorName=="Plus")
        writer.writeAttribute("operator","+");

    if(data.operatorName=="Multiplication")
        writer.writeAttribute("operator","*");

    if(data.operatorName=="And")
        writer.writeAttribute("operator","and");

    if(data.operatorName=="Or")
        writer.writeAttribute("operator","or");

    if(data.operatorName=="Exclusive Or")
        writer.writeAttribute("operator","xor");

    writer.writeStartElement("operands");

    for (int i=0;i<data.nAryOp.constVarRefs.size();i++)
    {
        saveIdExpression(writer,data.nAryOp.constVarRefs.at(i));

    }

    writer.writeEndElement();
    writer.writeEndElement();
}

void OperatorImporter::savePreOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("PreOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    writer.writeStartElement("flow");

    writer.writeStartElement("ListExpression");

    writer.writeStartElement("items");

    for (int i=0;i<data.preOp.flows.size();i++)
    {
        saveIdExpression(writer,data.preOp.flows.at(i));

    }

    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();
}

void OperatorImporter::saveInitOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("InitOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //value
    writer.writeStartElement("value");
    writer.writeStartElement("ListExpression");
    writer.writeStartElement("items");

    for (int i=0;i<data.initOp.parameters.size();i++)
    {
        saveParameter(writer,data.initOp.parameters.at(i));
    }

    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();

    //flow
    writer.writeStartElement("flow");

    writer.writeStartElement("ListExpression");

    writer.writeStartElement("items");

    for (int i=0;i<data.initOp.flows.size();i++)
    {
        saveIdExpression(writer,data.initOp.flows.at(i));
    }

    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();
}

void OperatorImporter::saveFbyOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("FbyOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //flows
    writer.writeStartElement("flows");
    for(int i=0;i<data.fbyOp.flows.size();i++)
    {
        saveIdExpression(writer,data.fbyOp.flows.at(i));
    }
    writer.writeEndElement();

    //delay
    writer.writeStartElement("delay");
    saveParameter(writer,data.fbyOp.delay);
    writer.writeEndElement();

    //values
    writer.writeStartElement("values");
    for(int i=0;i<data.fbyOp.parameters.size();i++)
    {
        saveParameter(writer,data.fbyOp.parameters.at(i));
    }
    writer.writeEndElement();

    writer.writeEndElement();
}

void OperatorImporter::savePrjOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("PrjOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //flow
    writer.writeStartElement("flow");
    saveIdExpression(writer,data.prjOp.flow);
    writer.writeEndElement();

    //with
    writer.writeStartElement("with");
    for(int i=0;i<data.prjOp.parameters.size();i++)
    {
        saveParameter(writer,data.prjOp.parameters.at(i));
    }
    writer.writeEndElement();

    writer.writeEndElement();
}

void OperatorImporter::saveSliceOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("SliceOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //array
    writer.writeStartElement("array");
    saveIdExpression(writer,data.sliceOp.array);
    writer.writeEndElement();

    //fromIndex
    writer.writeStartElement("fromIndex");
    saveParameter(writer,data.sliceOp.fromIndex);
    writer.writeEndElement();

    //toIndex
    writer.writeStartElement("toIndex");
    saveParameter(writer,data.sliceOp.toIndex);
    writer.writeEndElement();

    writer.writeEndElement();
}

void OperatorImporter::savePrjDynOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("PrjDynOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //array
    writer.writeStartElement("array");
    saveIdExpression(writer,data.prjDynOp.array);
    writer.writeEndElement();

    //indexes
    writer.writeStartElement("indexes");
    for(int i=0;i<data.prjDynOp.indexes.size();i++)
    {
        saveParameter(writer,data.prjDynOp.indexes.at(i));
    }
    writer.writeEndElement();

    //default
    writer.writeStartElement("default");
    saveParameter(writer,data.prjDynOp.defaultpara);
    writer.writeEndElement();

    writer.writeEndElement();
}

void OperatorImporter::saveDataStructOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("DataStructOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //data
    writer.writeStartElement("data");

    for(int i=0;i<data.dataStructOp.labels.size();i++)
    {
        writer.writeStartElement("LabelledExpression");
        writer.writeAttribute("label",data.dataStructOp.labels.at(i).labelName);
        writer.writeStartElement("flow");
        saveIdExpression(writer,data.dataStructOp.labels.at(i).value);

        writer.writeEndElement();
        writer.writeEndElement();
    }

    writer.writeEndElement();
    writer.writeEndElement();
}

void OperatorImporter::saveScalarToVectorOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("ScalarToVectorOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //flow
    writer.writeStartElement("flow");
    writer.writeStartElement("ListExpression");
    writer.writeStartElement("items");
    for(int i=0;i<data.scalarToVectorOp.flows.size();i++)
    {
        saveIdExpression(writer,data.scalarToVectorOp.flows.at(i));
    }
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();

    //size
    writer.writeStartElement("size");
    saveParameter(writer,data.scalarToVectorOp.size);
    writer.writeEndElement();

    writer.writeEndElement();
}

void OperatorImporter::saveDataArrayOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("DataArrayOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //data
    writer.writeStartElement("data");
    for(int i=0;i<data.dataArrayOp.datas.size();i++)
    {
        saveIdExpression(writer,data.dataArrayOp.datas.at(i));
    }
    writer.writeEndElement();

    writer.writeEndElement();
}

void OperatorImporter::saveChgIthOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("ChgIthOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //flow
    writer.writeStartElement("flow");
    saveIdExpression(writer,data.chgIthOp.flow);
    writer.writeEndElement();

    //with
    writer.writeStartElement("with");
    for(int i=0;i<data.chgIthOp.parameters.size();i++)
    {
        saveParameter(writer,data.chgIthOp.parameters.at(i));
    }
    writer.writeEndElement();

    //value
    writer.writeStartElement("value");
    saveIdExpression(writer,data.chgIthOp.value);
    writer.writeEndElement();

    writer.writeEndElement();

}

void OperatorImporter::saveIfThenElseOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("IfThenElseOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //if
    writer.writeStartElement("if");
    saveIdExpression(writer,data.ifThenElseOp.ifValue);
    writer.writeEndElement();

    //then
    writer.writeStartElement("then");
    writer.writeStartElement("ListExpression");
    writer.writeStartElement("items");
    for(int i=0;i<data.ifThenElseOp.thens.size();i++)
    {
        saveIdExpression(writer,data.ifThenElseOp.thens.at(i));
    }
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();

    //else
    writer.writeStartElement("else");
    writer.writeStartElement("ListExpression");
    writer.writeStartElement("items");
    for(int i=0;i<data.ifThenElseOp.elses.size();i++)
    {
        saveIdExpression(writer,data.ifThenElseOp.elses.at(i));
    }
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();

    writer.writeEndElement();
}

void OperatorImporter::saveCaseOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("CaseOp");

    writer.writeAttribute("name",QString("%1").arg(data.id));

    //switch
    writer.writeStartElement("switch");
    saveIdExpression(writer,data.caseOp.switchValue);
    writer.writeEndElement();

    //cases
    writer.writeStartElement("cases");

    for(int i=0;i<data.caseOp.cases.size();i++)
    {
        writer.writeStartElement("Case");
        writer.writeAttribute("pattern",data.caseOp.cases.at(i).labelName);
        writer.writeStartElement("flow");
        saveIdExpression(writer,data.caseOp.cases.at(i).value);
        writer.writeEndElement();
        writer.writeEndElement();
    }

    //default
    writer.writeStartElement("Case");
    writer.writeStartElement("flow");
    saveIdExpression(writer,data.caseOp.defaultValue);
    writer.writeEndElement();
    writer.writeEndElement();

    writer.writeEndElement();

    writer.writeEndElement();
}

void OperatorImporter::saveMakeOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("CallExpression");

    //operator
    writer.writeStartElement("operator");
    writer.writeStartElement("MakeOp");
    writer.writeAttribute("name",QString("%1").arg(data.id));
    writer.writeStartElement("type");
    writer.writeStartElement("TypeRef");
    writer.writeAttribute("name",data.makeOp.typeRef);

    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();


    //callParameters
    if(!data.makeOp.calls.isEmpty())
    {
        writer.writeStartElement("callParameters");
        for(int i=0;i<data.makeOp.calls.size();i++)
        {
            saveIdExpression(writer,data.makeOp.calls.at(i));
        }
        writer.writeEndElement();
    }

    writer.writeEndElement();
}

void OperatorImporter::saveFlattenOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("CallExpression");

    //operator
    writer.writeStartElement("operator");
    writer.writeStartElement("FlattenOp");
    writer.writeAttribute("name",QString("%1").arg(data.id));
    writer.writeStartElement("type");
    writer.writeStartElement("TypeRef");
    if(data.flattenOp.typeRef.isEmpty())
        writer.writeAttribute("name","_null");
    else {
        writer.writeAttribute("name",data.flattenOp.typeRef);
    }

    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();

    //callParameters
    writer.writeStartElement("callParameters");
    saveIdExpression(writer,data.flattenOp.call);
    writer.writeEndElement();

    writer.writeEndElement();
}

void OperatorImporter::saveIteratorOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("CallExpression");

    //operator
    writer.writeStartElement("operator");
    writer.writeStartElement("IteratorOp");
    writer.writeAttribute("iterator",data.iteratorOp.iteratorType);

    writer.writeStartElement("operator");
    if(data.iteratorOp.isMakeOp==false&&data.iteratorOp.isFlattenOp==false)
    {
        writer.writeStartElement("OpCall");
        writer.writeAttribute("name",QString("%1").arg(data.id));
        writer.writeStartElement("operator");
        writer.writeStartElement("OperatorRef");
        writer.writeAttribute("name",data.iteratorOp.operatorRef);

        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();
    }

    if(data.iteratorOp.isMakeOp==true)
    {
        writer.writeStartElement("MakeOp");
        writer.writeAttribute("name",QString("%1").arg(data.id));
        writer.writeStartElement("type");
        writer.writeStartElement("TypeRef");
        writer.writeAttribute("name",data.iteratorOp.makeRef);

        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();
    }

    if(data.iteratorOp.isFlattenOp==true)
    {
        writer.writeStartElement("FlattenOp");
        writer.writeAttribute("name",QString("%1").arg(data.id));
        writer.writeStartElement("type");
        writer.writeStartElement("TypeRef");

        if(data.iteratorOp.flattenRef.isEmpty())
            writer.writeAttribute("name","_null");
        else {
            writer.writeAttribute("name",data.iteratorOp.flattenRef);
        }

        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();
    }

    writer.writeEndElement();

    //size
    writer.writeStartElement("size");
    writer.writeStartElement("ConstValue");
    writer.writeAttribute("value",data.iteratorOp.size.value);

    writer.writeEndElement();
    writer.writeEndElement();

    writer.writeEndElement();
    writer.writeEndElement();

    //callParameters
    if(!data.iteratorOp.calls.isEmpty())
    {
        writer.writeStartElement("callParameters");

        for(int i=0;i<data.iteratorOp.calls.size();i++)
        {
            saveIdExpression(writer,data.iteratorOp.calls.at(i));
        }
        writer.writeEndElement();
    }

    writer.writeEndElement();
}

void OperatorImporter::savePartialIteratorOp(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("CallExpression");

    //operator
    writer.writeStartElement("operator");
    writer.writeStartElement("PartialIteratorOp");
    writer.writeAttribute("iterator",data.partialIteratorOp.partialIteratorType);

    writer.writeStartElement("operator");
    if(data.partialIteratorOp.isMakeOp==false&&data.partialIteratorOp.isFlattenOp==false)
    {
        writer.writeStartElement("OpCall");
        writer.writeAttribute("name",QString("%1").arg(data.id));
        writer.writeStartElement("operator");
        writer.writeStartElement("OperatorRef");
        writer.writeAttribute("name",data.partialIteratorOp.operatorRef);

        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();
    }

    if(data.partialIteratorOp.isMakeOp==true)
    {
        writer.writeStartElement("MakeOp");
        writer.writeAttribute("name",QString("%1").arg(data.id));
        writer.writeStartElement("type");
        writer.writeStartElement("TypeRef");
        writer.writeAttribute("name",data.partialIteratorOp.makeRef);

        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();
    }

    if(data.partialIteratorOp.isFlattenOp==true)
    {
        writer.writeStartElement("FlattenOp");
        writer.writeAttribute("name",QString("%1").arg(data.id));
        writer.writeStartElement("type");
        writer.writeStartElement("TypeRef");

        if(data.partialIteratorOp.flattenRef.isEmpty())
            writer.writeAttribute("name","_null");
        else {
            writer.writeAttribute("name",data.partialIteratorOp.flattenRef);
        }

        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();
    }

    writer.writeEndElement();

    //size
    writer.writeStartElement("size");
    writer.writeStartElement("ConstValue");
    writer.writeAttribute("value",data.partialIteratorOp.size.value);

    writer.writeEndElement();
    writer.writeEndElement();

    //if
    writer.writeStartElement("if");
    saveIdExpression(writer,data.partialIteratorOp.ifValue);
    writer.writeEndElement();

    //default
    if(data.partialIteratorOp.partialIteratorType=="mapw"||data.partialIteratorOp.partialIteratorType=="mapwi")
    {
        writer.writeStartElement("default");
        writer.writeStartElement("ListExpression");

        writer.writeEndElement();
        writer.writeEndElement();
    }

    writer.writeEndElement();
    writer.writeEndElement();

    //callParameters
    if(!data.partialIteratorOp.calls.isEmpty())
    {
        writer.writeStartElement("callParameters");

        for(int i=0;i<data.partialIteratorOp.calls.size();i++)
        {
            saveIdExpression(writer,data.partialIteratorOp.calls.at(i));
        }
        writer.writeEndElement();
    }

    writer.writeEndElement();

}

void OperatorImporter::saveOpCall(QXmlStreamWriter &writer,const Equation &data)
{
    writer.writeStartElement("CallExpression");

    //operator
    writer.writeStartElement("operator");
    writer.writeStartElement("OpCall");
    writer.writeAttribute("name",QString("%1").arg(data.id));
    writer.writeStartElement("operator");
    writer.writeStartElement("OperatorRef");
    writer.writeAttribute("name",data.opCall.operatorRef);

    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();

    //callParameters
    if(!data.opCall.calls.isEmpty())
    {
        writer.writeStartElement("callParameters");
        for(int i=0;i<data.opCall.calls.size();i++)
        {
            saveIdExpression(writer,data.opCall.calls.at(i));
        }
        writer.writeEndElement();
    }

    writer.writeEndElement();
}

void OperatorImporter::saveIdExpression(QXmlStreamWriter &writer,const QString &data)
{
    writer.writeStartElement("IdExpression");
    writer.writeStartElement("path");
    writer.writeStartElement("ConstVarRef");
    if(data.isEmpty())
        writer.writeAttribute("name","_null");
    else {
        writer.writeAttribute("name",data);
    }

    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeEndElement();
}

void OperatorImporter::saveParameter(QXmlStreamWriter &writer,const parameter &data)
{
    if(data.isImmediate==false)
        saveIdExpression(writer,data.value);
    else {
        writer.writeStartElement("ConstValue");
        writer.writeAttribute("value",data.value);
        writer.writeEndElement();
    }
}

QList<Variable> OperatorImporter::parseVariables(const QDomElement &element)
{
    QList<Variable> varList;

    QDomNodeList items=element.childNodes();
    for (int i = 0;i < items.count();i++)
    {
        Variable data;

        if(element.tagName()=="inputs")
            data.type="input";

        if(element.tagName()=="outputs")
            data.type="output";

        if(element.tagName()=="locals")
            data.type="local";

        QDomNode item = items.at(i);
        data.node=items.at(i);

        QDomElement ele = item.toElement();

        QDomNode typeNode;
        QDomNode lastNode;
        QDomNode defaultNode;
        QDomNode idNode;
        QDomNode pragmasNode;
        QDomNode commentNode;

        QDomNodeList nodeList=ele.childNodes();

        for(int i=0;i<nodeList.size();i++)
        {
            if(nodeList.at(i).toElement().tagName()=="type")
                typeNode=ele.childNodes().at(i);

            if(nodeList.at(i).toElement().tagName()=="default")
                defaultNode=ele.childNodes().at(i);

            if(nodeList.at(i).toElement().tagName()=="last")
                lastNode=ele.childNodes().at(i);

            if(nodeList.at(i).toElement().tagName()=="pragmas")
                pragmasNode=ele.childNodes().at(i);
        }

        QDomElement typeEle=typeNode.firstChild().toElement();

        idNode=pragmasNode.namedItem("ed:Variable");

        //报告隐藏变量
        if(idNode.toElement().attribute("hidden")=="true")
        {
            m_operator.logList.append("变量"+data.name+"为隐藏变量");
        }

        if(!idNode.namedItem("comment").isNull())
            commentNode=idNode.firstChild();

        data.id=getOid(idNode);


        data.comment=getComment(commentNode);

        data.name=ele.attribute("name");

        QString tagName=typeEle.tagName();

        //解析普通类型变量
        if(tagName=="NamedType")
        {
            parseNomalVariable(data,typeEle);
        }

        //解析结构体类型变量
        if(tagName=="Struct")
        {
            data.isStruct=true;
            parseStructVariable(data,typeEle);
        }

        //解析数组类型变量
        if(tagName=="Table")
        {
            data.isArray=true;
            parseArrayVariable(data,typeEle);
        }

        //报告变量和操作符重名
        if(data.name==m_operator.operatorName)
        {
            m_operator.logList.append("变量"+data.name+"与操作符重名");
        }

        //default
        if(!defaultNode.isNull())
        {
            //default为表达式时
            if(defaultNode.firstChild().isComment())
            {
                data.defaultNode=defaultNode.childNodes().at(1);
                data.defaultValue=defaultNode.firstChild().nodeValue();
            }
            else
            {
                data.defaultNode=defaultNode.firstChild().cloneNode(true);
                if(defaultNode.firstChild().toElement().tagName()=="IdExpression")
                {
                    data.defaultValue=defaultNode.firstChild().firstChild().firstChild().toElement().attribute("name");
                }

                if(defaultNode.firstChild().toElement().tagName()=="ConstValue")
                {
                    data.defaultValue=defaultNode.firstChild().toElement().attribute("value");
                }
            }

            //m_operator.logList.append("变量"+data.name+"有默认值,默认值为"+data.defaultValue);
        }

        //Last
        if(!lastNode.isNull())
        {
            //last值为表达式时
            if(lastNode.firstChild().isComment())
            {
                data.lastNode=lastNode.childNodes().at(1);
                data.lastValue=lastNode.firstChild().nodeValue();

            }
            else {
                data.lastNode=lastNode.firstChild().cloneNode(true);
                if(lastNode.firstChild().toElement().tagName()=="IdExpression")
                {
                    data.lastValue=lastNode.firstChild().firstChild().firstChild().toElement().attribute("name");
                }

                if(lastNode.firstChild().toElement().tagName()=="ConstValue")
                {
                    data.lastValue=lastNode.firstChild().toElement().attribute("value");
                }
            }

        }

        if(data.type=="local"&&data.name.startsWith("_L")&&data.name.mid(2).contains(QRegExp("^\\d+$")))//本地变量名以_L开头，后续为纯数字认为为端口
            data.isLine=true;

        varList.append(data);

    }

    return varList;
}

void OperatorImporter::parseNomalVariable(Variable &data,const QDomElement &element)
{
    QDomElement typeRefElement=element.firstChild().firstChild().toElement();

    data.dataType=typeRefElement.attribute("name");
    //报告泛型
    if(data.dataType=="'T")
    {
        data.hasT=true;
        m_operator.hasT=true;
        m_operator.logList.append("变量"+data.name+"为'T");
    }
}

void OperatorImporter::parseStructVariable(Variable &data,const QDomElement &element)
{
    QDomNodeList fieldList=element.firstChild().childNodes();

    data.dataType="{";

    for(int i=0;i<fieldList.size();i++)
    {
        Field field;

        QDomNode fieldNode=fieldList.at(i);
        QDomNode typeNode=fieldNode.firstChild();
        QDomNode pragmasNode=typeNode.nextSibling();
        QDomNode typeRefNode=typeNode.firstChild().firstChild().firstChild();

        field.name=fieldNode.toElement().attribute("name");
        field.type=typeRefNode.toElement().attribute("name");
        field.oid=pragmasNode.firstChild().toElement().attribute("oid");
        data.dataType=data.dataType+field.name+":"+field.type;

        if(i!=fieldList.size()-1)
        {
            data.dataType=data.dataType+",";
        }

        //报告结构体元素中的泛型
        if(field.type=="'T")
        {
            data.hasT=true;
            m_operator.hasT=true;
            m_operator.logList.append("结构体变量"+data.name+"的元素"+field.name+"为'T");
        }

        data.fieldList.append(field);
    }

    data.dataType=data.dataType+"}";

}

void OperatorImporter::parseArrayVariable(Variable &data,const QDomElement &element)
{
    QDomNode typeNode=element.firstChild();
    QDomNode indexNode=typeNode.firstChild();

    if(indexNode.toElement().tagName()=="NamedType")
    {
        QDomNode typeRefNode=indexNode.firstChild().firstChild();
        data.array.type=typeRefNode.toElement().attribute("name");

        //报告泛型数组
        if(data.array.type=="'T")
        {
            data.hasT=true;
            m_operator.hasT=true;
            m_operator.logList.append("数组变量"+data.name+"的数据类型为'T");
        }
    }

    //报告结构体数组泛型
    if(indexNode.toElement().tagName()=="Struct")
    {
        QDomNode fieldsNode=indexNode.firstChild();
        QDomNodeList nodeList=fieldsNode.childNodes();

        for(int i=0;i<nodeList.size();i++)
        {
            QDomNode node=nodeList.at(i);
            QString fieldName=node.toElement().attribute("name");
            QDomNode typeRef=node.firstChild().firstChild().firstChild().firstChild();

            if(typeRef.toElement().attribute("name")=="'T")
            {
                data.hasT=true;
                m_operator.hasT=true;
                m_operator.logList.append("结构体数组变量"+data.name+"的元素"+fieldName+"为'T");
            }
        }
    }

//    QDomNode typeRefNode=typeNode.firstChild().firstChild().firstChild();
    QDomNode sizeNode=typeNode.nextSibling();

//    data.array.type=typeRefNode.toElement().attribute("name");

    if(sizeNode.childNodes().size()==2)
    {
        data.array.size=parseParameter(sizeNode.childNodes().at(1).toElement());
    }
    else {
        data.array.size=parseParameter(sizeNode.firstChild().toElement());
    }

    //判断数组大小是否为参数
    if(data.array.size.value==m_operator.parameter)
        data.hasPara=true;

    data.dataType=data.array.type+"^"+data.array.size.value;

}

void OperatorImporter::parseDatas(const QDomElement &element)
{
    QDomNodeList items=element.childNodes();

    //获取所有页面的EquationGE
    QDomNode operatorNode=element.parentNode();

    QDomNodeList nodeList=operatorNode.childNodes();

    QList<QDomNode> equationGEList;

    for(int i=0;i<nodeList.size();i++)
    {
        if(nodeList.at(i).toElement().tagName()=="pragmas")
        {
            QDomNode pragmasNode=nodeList.at(i);

            QDomNodeList list=pragmasNode.firstChild().childNodes();

            for(int i=0;i<list.size();i++)
            {
                if(list.at(i).toElement().tagName()=="diagrams")
                {
                    QDomNode diagramsNode=list.at(i);

                    QDomNodeList diagList=diagramsNode.childNodes();

                    for(int i=0;i<diagList.size();i++)
                    {
                        QDomNodeList nodeList=diagList.at(i).firstChild().childNodes();

                        for(int i=0;i<nodeList.size();i++)
                        {
                            if(nodeList.at(i).toElement().tagName()=="EquationGE")
                                equationGEList.append(nodeList.at(i));
                        }
                    }
                }
            }

        }
    }

    for (int i = 0;i < items.count();i++)
    {
        if(!element.hasChildNodes())
            return;

        QDomNode item = items.at(i);
        QDomElement ele = item.toElement();

        //状态机
        if(ele.tagName()=="StateMachine")
        {
            parseStateMachine(ele,equationGEList,"");
        }

        //ifblock
        if(ele.tagName()=="IfBlock")
        {
            parseIfBlock(ele,equationGEList);
        }

        if(ele.tagName()=="Equation")
        {
            m_operator.equations.append(parseEquation(ele,equationGEList,QList<Variable>()));
        }

        if(ele.tagName()=="Emission")
        {
            Equation data;

            QDomElement signalsEle=ele.namedItem("signals").toElement();
            QDomElement conditionEle=ele.namedItem("condition").toElement();
            QDomElement pragmasEle=ele.namedItem("pragmas").toElement();
            QDomNode idNode=pragmasEle.namedItem("ed:Emission");
            QDomNode commentNode=idNode.namedItem("comment");
            QDomElement signalRefEle=signalsEle.namedItem("SignalRef").toElement();
            QDomElement constVarRef=conditionEle.firstChild().firstChild().firstChild().toElement();

            data.node=ele;
            data.oid=getOid(idNode);
            data.redaceId=QUuid::createUuid().toString(QUuid::WithoutBraces);
            data.comment=getComment(commentNode);
            data.type="emitSignal";
            data.name=signalRefEle.attribute("name");
            data.lefts.append(data.name);
            data.rightVarRef=constVarRef.attribute("name");
            m_operator.equations.append(data);
        }
    }
}

Equation OperatorImporter::parseEquation(const QDomElement &element,const QList<QDomNode>& equationGEList,const QList<Variable>& variables)
{
    QDomElement leftsEle=element.namedItem("lefts").toElement();
    QDomElement rightEle=element.namedItem("right").toElement();
    QDomElement pragmasEle=element.namedItem("pragmas").toElement();

    QDomNode idNode=pragmasEle.firstChild();
    QDomNode commentNode;

    if(idNode.hasChildNodes()&&idNode.firstChild().toElement().tagName()=="comment")
        commentNode=idNode.firstChild();

    QDomNodeList variableRefs=leftsEle.childNodes();

    Equation data;

    data.node=element;
    data.oid=getOid(idNode);
    data.redaceId=QUuid::createUuid().toString(QUuid::WithoutBraces);
    data.comment=getComment(commentNode);

    //判断图元类型
    //变量、常量、结束符
    if(rightEle.firstChild().toElement().tagName()=="IdExpression"||rightEle.firstChild().toElement().tagName()=="Last"||rightEle.firstChild().toElement().tagName()=="Present")
    {
        QDomElement constVarRef=rightEle.firstChild().firstChild().firstChild().toElement();

        QString variableRefName=variableRefs.at(0).toElement().attribute("name");

        QString constVarRefName;
        if(constVarRef.hasAttribute("name"))
            constVarRefName=constVarRef.attribute("name");

        QList<Variable> varList=variables+m_operator.variables;

        for(int i = 0;i < varList.size();i++)
        {
            Variable var=varList.at(i);

            if(rightEle.firstChild().toElement().tagName()=="Last")
            {
                if(var.name==constVarRefName)
                {
                    data.isLastVar=true;

                    if(var.type=="input")
                    {
                        data.type="lastInputVar";
                    }
                    else if(var.type=="output")
                    {
                        data.type="lastOutputVar";
                    }
                    else if(var.type=="local")
                    {
                        data.type="lastLocalVar";
                    }
                    else if(var.type=="signal")
                    {
                        data.type="lastSignal";
                    }

                    data.lefts.append(variableRefName);
                    data.rightVarRef=constVarRefName;
                    data.name=var.name;
                }

            }
            else {
                //present信号量
                if(var.type=="signal"&&var.name==constVarRefName)
                {
                    data.type="presentSignal";
                    data.lefts.append(variableRefName);
                    data.name=var.name;
                    data.rightVarRef=constVarRefName;
                }

                //输入变量
                if(var.type=="input"&&var.name==constVarRefName)
                {
                    data.type="inputVar";
                    data.lefts.append(variableRefName);
                    data.name=var.name;
                    data.rightVarRef=constVarRefName;
                }

                //输出变量
                if(var.type=="output"&&var.name==variableRefs.at(0).toElement().attribute("name"))
                {
                    data.type="outputVar";
                    data.lefts.append(var.name);
                    data.name=var.name;
                    data.rightVarRef=constVarRefName;
                }

                //本地输入变量
                if(var.type=="local"&&var.isLine==false&&var.name==constVarRefName&&data.type.isEmpty())
                {
                    data.type="localInputVar";
                    data.lefts.append(variableRefName);
                    data.name=var.name;
                    data.rightVarRef=constVarRefName;

                }

                //本地输出变量
                if(var.type=="local"&&var.isLine==false&&var.name==variableRefs.at(0).toElement().attribute("name")&&data.type.isEmpty())
                {
                    data.type="localOutputVar";
                    data.lefts.append(var.name);
                    data.name=var.name;
                    data.rightVarRef=constVarRefName;
                }

            }
        }

        //常量
        if(data.type.isEmpty()&&variableRefName!="_")
        {
            data.type="constant";
            data.lefts.append(variableRefName);

            //处理包中的常量
            if(constVarRefName.contains("::"))
            {
                QStringList list=constVarRefName.split("::");
                constVarRefName=list.at(list.size()-1);
                constVarRef.setAttribute("name",constVarRefName);
            }

            data.name=constVarRefName;
            data.rightVarRef=constVarRefName;

            //参数输入
            if(constVarRefName==m_operator.parameter)
            {
                data.isParaHigh=true;
            }

        }

        //结束符
        if(data.type.isEmpty()&&variableRefName=="_")
        {
            data.type="terminator";
            data.lefts.append(variableRefName);
            //                    data.name=constVarRefName;
            data.rightVarRef=constVarRefName;
        }

    }
    else
    {
        //立即数
        for(int i=0;i<equationGEList.size();i++)
        {
            if(data.oid==equationGEList.at(i).toElement().attribute("presentable"))
            {
                if(equationGEList.at(i).toElement().hasAttribute("kind")&&equationGEList.at(i).toElement().attribute("kind")=="OBJ_LIT")
                {
                    data.type="immediate";
                    data.lefts.append(variableRefs.at(0).toElement().attribute("name"));

                    QDomNodeList rightChild=rightEle.childNodes();

                    //有注释
                    if(rightChild.size()==2)
                    {
                        data.text=rightEle.firstChild().nodeValue();

                    }
                    else
                    {
                        if(rightEle.firstChild().toElement().tagName()=="ConstValue")
                        {
                            data.rightVarRef=rightEle.firstChild().toElement().attribute("value");
                            data.text=data.rightVarRef;
                        }

                        if(rightEle.firstChild().toElement().tagName()=="TextExpression")
                        {
                            data.text=rightEle.firstChild().toElement().attribute("text");
                        }

                    }

                    //解析立即数为整数或浮点数时对应的基础数据类型，以加上对应后缀
                    QRegularExpression regex("^[-+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][-+]?\\d+)?$");
                    if(regex.match(data.text).hasMatch())
                    {
                        if(variables.isEmpty())
                        {
                            for(auto var:m_operator.variables)
                            {
                                if(data.lefts.at(0)==var.name)
                                {
                                    data.immediateType=var.dataType;
                                }
                            }
                        }
                        else
                        {
                            for(auto var:variables)
                            {
                                if(data.lefts.at(0)==var.name)
                                {
                                    data.immediateType=var.dataType;
                                }
                            }
                        }
                    }


                }

            }

        }

        //操作符
        if(data.type.isEmpty())
        {
            data.type="operator";//操作符
            for(int i=0;i<variableRefs.size();i++)
            {
                data.lefts.append(variableRefs.at(i).toElement().attribute("name"));
            }

            QDomElement operatorEle=rightEle.firstChild().nextSibling().toElement();
            parseBaseOperator(operatorEle,data);
        }

    }

    return data;
}

QString OperatorImporter::getOid(const QDomNode &idNode)
{
    // 获取oid
    QString oid;
    QDomElement idElement = idNode.toElement();
    if(idElement.hasAttribute("oid"))
    {
        oid = idElement.attribute("oid");
    }
    return  oid;
}

QString OperatorImporter::getComment(const QDomNode &commentNode)
{
    // 获取描述信息
    QString comment;
    QDomElement comtElement = commentNode.toElement();

    comment = comtElement.text();

    return comment;
}

void OperatorImporter::parseBaseOperator(const QDomElement &element,Equation &data)
{
    QString tagName=element.tagName();

    //一元操作符
    if(tagName=="UnaryOp")
        parseUnaryOp(element,data);

    //二元操作符
    if(tagName=="BinaryOp")
        parseBinaryOp(element,data);

    //多元操作符
    if(tagName=="NAryOp")
        parseNAryOp(element,data);

    //时序操作符
    //Previous
    if(tagName=="PreOp")
        parsePreOp(element,data);

    //Init
    if(tagName=="InitOp")
        parseInitOp(element,data);

    //Followed By
    if(tagName=="FbyOp")
        parseFbyOp(element,data);

    //Projection
    if(tagName=="PrjOp")
        parsePrjOp(element,data);

    //Slice
    if(tagName=="SliceOp")
        parseSliceOp(element,data);

    //Dynamic Projection
    if(tagName=="PrjDynOp")
        parsePrjDynOp(element,data);

    //DataStructure
    if(tagName=="DataStructOp")
        parseDataStructOp(element,data);

    //ScalarToVector
    if(tagName=="ScalarToVectorOp")
        parseScalarToVectorOp(element,data);

    //DataArray
    if(tagName=="DataArrayOp")
        parseDataArrayOp(element,data);

    //Assign of a Structured Element
    if(tagName=="ChgIthOp")
        parseChgIthOp(element,data);

    //If Then Else
    if(tagName=="IfThenElseOp")
        parseIfThenElseOp(element,data);

    //Case
    if(tagName=="CaseOp")
        parseCaseOp(element,data);

    //ExprOp
    if(tagName=="CallExpression")
    {
        QDomElement operatorEle=element.firstChild().toElement();

        //Make
        if(operatorEle.tagName()=="operator"&&operatorEle.firstChild().toElement().tagName()=="MakeOp")
            parseMakeOp(element,data);

        //Flatten
        if(operatorEle.tagName()=="operator"&&operatorEle.firstChild().toElement().tagName()=="FlattenOp")
            parseFlattenOp(element,data);

        //Iterator
        if(operatorEle.tagName()=="operator"&&operatorEle.firstChild().toElement().tagName()=="IteratorOp")
            parseIteratorOp(element,data);

        //Partiallterator
        if(operatorEle.tagName()=="operator"&&operatorEle.firstChild().toElement().tagName()=="PartialIteratorOp")
            parsePartialIteratorOp(element,data);

        //自定义操作符
        if(operatorEle.tagName()=="operator"&&operatorEle.firstChild().toElement().tagName()=="OpCall")
            parseOpCall(element,data);

        //Boolean Activate
        if(operatorEle.tagName()=="operator"&&(operatorEle.firstChild().toElement().tagName()=="ActivateOp"||operatorEle.firstChild().toElement().tagName()=="ActivateNoInitOp"))
        {
            parseActivateOp(element,data);
        }

        //Restart
        if(operatorEle.tagName()=="operator"&&operatorEle.firstChild().toElement().tagName()=="RestartOp")
        {
            parseRestartOp(element,data);
        }

    }

    if(tagName=="TransposeOp")
    {
        parseTransposeOp(element,data);
    }

    if(tagName=="NumericCastOp")
    {
        parseNumericCastOp(element,data);
    }

}

void OperatorImporter::parseUnaryOp(const QDomElement &element,Equation &data)
{
    data.operatorType="UnaryOp";

    if(!element.hasAttribute("operator"))
        return;

    QString operatorName=element.attribute("operator");

    //Unary Minus取反运算
    if(operatorName=="-")
        data.operatorName="Unary Minus";

    //Not非运算
    if(operatorName=="not")
        data.operatorName="Not";

    //Convert To Integer强制转换为整数运算
    if(operatorName=="int")
        data.operatorName="Convert To Integer";

    //Convert To Real强制转换换浮点数运算
    if(operatorName=="real")
        data.operatorName="Convert To Real";

    //Reverse
    if(operatorName=="reverse")
    {
        data.operatorName="Reverse";
    }

    //lnot
    if(operatorName=="lnot")
    {
        data.operatorName="Bitwise Not";
    }

    QDomElement operandEle=element.firstChild().toElement();

    if(operandEle.tagName()!="operand")
        return;

    QDomElement idExpressionEle=operandEle.firstChild().toElement();

    data.unaryOp.constVarRef=parseIdExpression(idExpressionEle);

}

void OperatorImporter::parseBinaryOp(const QDomElement &element,Equation &data)
{
    if(!element.hasAttribute("operator"))
        return;

    QString operatorName=element.attribute("operator");

    if(operatorName=="times")
    {
        data.operatorType="TimesOp";

        QDomElement operandsEle=element.namedItem("operands").toElement();
        QDomElement counterEle=operandsEle.firstChildElement();
        QDomElement conditionEle=counterEle.nextSiblingElement();

        data.timesOp.counter=parseParameter(counterEle);
        data.timesOp.condition=parseIdExpression(conditionEle);
    }
    else if(operatorName=="lsl")
    {
        data.operatorType="LslOp";
        QDomElement operandsEle=element.namedItem("operands").toElement();
        QDomElement inputEle=operandsEle.firstChildElement();
        QDomElement numberEle=inputEle.nextSiblingElement();
        data.lslOp.input=parseIdExpression(inputEle);
        data.lslOp.number=parseParameter(numberEle);
    }
    else if(operatorName=="lsr")
    {
        data.operatorType="LsrOp";
        QDomElement operandsEle=element.namedItem("operands").toElement();
        QDomElement inputEle=operandsEle.firstChildElement();
        QDomElement numberEle=inputEle.nextSiblingElement();
        data.lsrOp.input=parseIdExpression(inputEle);
        data.lsrOp.number=parseParameter(numberEle);
    }
    else
    {
        data.operatorType="BinaryOp";
        //Minus 减法运算
        if(operatorName=="-")
            data.operatorName="Minus";

        //Polymorphic Division 除法运算（输出值为浮点数）
        if(operatorName=="/")
            data.operatorName="Polymorphic Division";

        //Integer Division 除法运算（输出值为整数）
        if(operatorName=="div")
            data.operatorName="Integer Division";

        //Modulo 求余运算
        if(operatorName=="mod")
            data.operatorName="Modulo";

        //Strictly Less Than  <
        if(operatorName=="<")
            data.operatorName="Strictly Less Than";

        //Less Than Or Equal   <=
        if(operatorName=="<=")
            data.operatorName="Less Than Or Equal";

        //Strictly Greater Than  >
        if(operatorName==">")
            data.operatorName="Strictly Greater Than";

        //Greater Than Or Equal   >=
        if(operatorName==">=")
            data.operatorName="Greater Than Or Equal";

        //Different  !=
        if(operatorName=="<>")
            data.operatorName="Different";

        //Equal    ==
        if(operatorName=="=")
            data.operatorName="Equal";

        //lxor
        if(operatorName=="lxor")
            data.operatorName="Bitwise Exclusive Or";

        QDomElement operandsEle=element.firstChild().toElement();

        if(operandsEle.tagName()!="operands")
            return;

        QDomNodeList idExpressionNodes=operandsEle.childNodes();

        for(int i=0;i<idExpressionNodes.size();i++)
        {
            data.binaryOp.constVarRefs.append(parseIdExpression(idExpressionNodes.at(i).toElement()));
        }
    }

}

void OperatorImporter::parseNAryOp(const QDomElement &element,Equation &data)
{
    data.operatorType="NAryOp";

    if(!element.hasAttribute("operator"))
        return;

    QString operatorName=element.attribute("operator");

    //Plus加法运算
    if(operatorName=="+")
        data.operatorName="Plus";

    //Multiplication乘法运算
    if(operatorName=="*")
        data.operatorName="Multiplication";

    //And 与运算
    if(operatorName=="and")
        data.operatorName="And";

    //Or 或运算
    if(operatorName=="or")
        data.operatorName="Or";

    //Exclusive Or异或运算
    if(operatorName=="xor")
        data.operatorName="Exclusive Or";

    //Concatenation
    if(operatorName=="@")
    {
        data.operatorName="Concatenation";
    }

    if(operatorName=="land")
    {
        data.operatorName="Bitwise And";
    }

    if(operatorName=="lor")
    {
        data.operatorName="Bitwise Or";
    }

    QDomElement operandsEle=element.firstChild().toElement();

    if(operandsEle.tagName()!="operands")
        return;

    QDomNodeList idExpressionNodes=operandsEle.childNodes();

    for(int i=0;i<idExpressionNodes.size();i++)
    {
        data.nAryOp.constVarRefs.append(parseIdExpression(idExpressionNodes.at(i).toElement()));
    }

}

void OperatorImporter::parsePreOp(const QDomElement &element,Equation &data)
{
    data.operatorType="PreOp";

    QDomElement flowEle=element.firstChild().toElement();
    if(flowEle.tagName()!="flow")
        return;

    QDomElement listEle=flowEle.firstChild().toElement();
    if(listEle.tagName()!="ListExpression")
        return;

    QDomElement itemsEle=listEle.firstChild().toElement();
    if(itemsEle.tagName()!="items")
        return;

    QDomNodeList itemsChilds=itemsEle.childNodes();

    for(int i=0;i<itemsChilds.size();i++)
    {
        data.preOp.flows.append(parseIdExpression(itemsChilds.at(i).toElement()));
    }

}

void OperatorImporter::parseInitOp(const QDomElement &element,Equation &data)
{
    data.operatorType="InitOp";

    QDomElement valueEle=element.firstChild().toElement();
    if(valueEle.tagName()!="value")
        return;

    QDomElement flowEle=element.firstChild().nextSibling().toElement();
    if(flowEle.tagName()!="flow")
        return;

    //参数
    QDomNodeList valueChilds=valueEle.firstChild().firstChild().childNodes();
    for(int i=0;i<valueChilds.size();i++)
    {
        if(!valueChilds.at(i).isComment())
        {
            QDomElement valueChildEle=valueChilds.at(i).toElement();

            data.initOp.parameters.append(parseParameter(valueChildEle));
        }
    }

    //输入端口
    QDomNodeList flowChilds=flowEle.firstChild().firstChild().childNodes();
    for(int i=0;i<flowChilds.size();i++)
    {
        QDomElement flowChildEle=flowChilds.at(i).toElement();

        data.initOp.flows.append(parseIdExpression(flowChildEle));
    }

}

void OperatorImporter::parseFbyOp(const QDomElement &element,Equation &data)
{
    data.operatorType="FbyOp";

    QDomElement flowsEle=element.firstChild().toElement();
    if(flowsEle.tagName()!="flows")
        return;

    QDomElement delayEle=element.firstChild().nextSibling().toElement();
    if(delayEle.tagName()!="delay")
        return;

    QDomElement valuesEle=element.firstChild().nextSibling().nextSibling().toElement();
    if(valuesEle.tagName()!="values")
        return;

    //输入
    QDomNodeList flowsChilds=flowsEle.childNodes();
    for(int i=0;i<flowsChilds.size();i++)
    {
        QDomElement flowChildEle=flowsChilds.at(i).toElement();

        data.fbyOp.flows.append(parseIdExpression(flowChildEle));
    }

    //delay
    if(delayEle.childNodes().size()==2)
    {
        QDomElement delayChild=delayEle.childNodes().at(1).toElement();

        data.fbyOp.delay=parseParameter(delayChild);
    }
    else {
        QDomElement delayChild=delayEle.firstChild().toElement();

        data.fbyOp.delay=parseParameter(delayChild);
    }

    //其他参数
    QDomNodeList valuesChilds=valuesEle.childNodes();
    for(int i=0;i<valuesChilds.size();i++)
    {
        if(!valuesChilds.at(i).isComment())
        {
            QDomElement valueChildEle=valuesChilds.at(i).toElement();

            data.fbyOp.parameters.append(parseParameter(valueChildEle));
        }
    }
}

void OperatorImporter::parsePrjOp(const QDomElement &element,Equation &data)
{
    data.operatorType="PrjOp";

    QDomElement flowEle=element.firstChild().toElement();
    if(flowEle.tagName()!="flow")
        return;

    QDomElement withEle=element.firstChild().nextSibling().toElement();
    if(withEle.tagName()!="with")
        return;

    //输入
    QDomElement flowChildEle=flowEle.firstChild().toElement();
    data.prjOp.flow=parseIdExpression(flowChildEle);

    //参数
    QDomNodeList withChilds=withEle.childNodes();
    for(int i=0;i<withChilds.size();i++)
    {
        if(!withChilds.at(i).isComment())
        {
            QDomElement withChildEle=withChilds.at(i).toElement();

            if(withChildEle.tagName()!="Label")
            {
                data.prjOp.parameters.append(parseParameter(withChildEle));
            }
            else
            {
                parameter para;
                para.value=withChildEle.attribute("name");
                data.prjOp.parameters.append(para);
            }

        }
    }
}

void OperatorImporter::parseSliceOp(const QDomElement &element,Equation &data)
{
    data.operatorType="SliceOp";

    QDomElement arrayEle=element.firstChild().toElement();
    if(arrayEle.tagName()!="array")
        return;

    QDomElement fromIndexEle=element.firstChild().nextSibling().toElement();
    if(fromIndexEle.tagName()!="fromIndex")
        return;

    QDomElement toIndexEle=element.firstChild().nextSibling().nextSibling().toElement();
    if(toIndexEle.tagName()!="toIndex")
        return;

    //array
    data.sliceOp.array=parseIdExpression(arrayEle.firstChild().toElement());

    //fromIndex
    if(fromIndexEle.childNodes().size()==2)
    {
        data.sliceOp.fromIndex=parseParameter(fromIndexEle.childNodes().at(1).toElement());
    }
    else {
        data.sliceOp.fromIndex=parseParameter(fromIndexEle.firstChild().toElement());
    }


    //toIndex
    if(toIndexEle.childNodes().size()==2)
    {
        data.sliceOp.toIndex=parseParameter(toIndexEle.childNodes().at(1).toElement());
    }
    else {
        data.sliceOp.toIndex=parseParameter(toIndexEle.firstChild().toElement());
    }


}

void OperatorImporter::parsePrjDynOp(const QDomElement &element,Equation &data)
{
    data.operatorType="PrjDynOp";

    QDomElement arrayEle=element.firstChild().toElement();
    if(arrayEle.tagName()!="array")
        return;

    QDomElement indexesEle=element.firstChild().nextSibling().toElement();
    if(indexesEle.tagName()!="indexes")
        return;

    QDomElement defaultEle=element.firstChild().nextSibling().nextSibling().toElement();
    if(defaultEle.tagName()!="default")
        return;

    data.prjDynOp.array=parseIdExpression(arrayEle.firstChild().toElement());

    QDomNodeList indexesChilds=indexesEle.childNodes();
    for(int i=0;i<indexesChilds.size();i++)
    {
        if(!indexesChilds.at(i).isComment())
        {
            QDomElement indexesChildEle=indexesChilds.at(i).toElement();

            data.prjDynOp.indexes.append(parseParameter(indexesChildEle));
        }

    }

    if(defaultEle.childNodes().size()==2)
    {
        data.prjDynOp.defaultpara=parseParameter(defaultEle.childNodes().at(1).toElement());
    }
    else {
        data.prjDynOp.defaultpara=parseParameter(defaultEle.firstChild().toElement());
    }

}

void OperatorImporter::parseDataStructOp(const QDomElement &element,Equation &data)
{
    data.operatorType="DataStructOp";

    QDomElement dataEle=element.firstChild().toElement();

    if(dataEle.tagName()!="data")
        return;

    QDomNodeList labels=dataEle.childNodes();

    for(int i=0;i<labels.size();i++)
    {
        QDomElement labelEle=labels.at(i).toElement();

        label item;
        item.labelName=labelEle.attribute("label");
        item.value=parseIdExpression(labelEle.firstChild().firstChild().toElement());

        data.dataStructOp.labels.append(item);

    }

}

void OperatorImporter::parseScalarToVectorOp(const QDomElement &element,Equation &data)
{
    data.operatorType="ScalarToVectorOp";

    QDomElement flowEle=element.firstChild().toElement();
    if(flowEle.tagName()!="flow")
        return;

    QDomElement sizeEle=element.firstChild().nextSibling().toElement();
    if(sizeEle.tagName()!="size")
        return;

    QDomNodeList itemsChilds=flowEle.firstChild().firstChild().childNodes();

    for(int i=0;i<itemsChilds.size();i++)
    {
        QDomElement itemsChildEle=itemsChilds.at(i).toElement();
        data.scalarToVectorOp.flows.append(parseIdExpression(itemsChildEle));
    }

    if(sizeEle.childNodes().size()==2)
    {
        data.scalarToVectorOp.size=parseParameter(sizeEle.childNodes().at(1).toElement());
    }
    else {
        data.scalarToVectorOp.size=parseParameter(sizeEle.firstChild().toElement());
    }

}

void OperatorImporter::parseDataArrayOp(const QDomElement &element,Equation &data)
{
    data.operatorType="DataArrayOp";

    QDomElement dataEle=element.firstChild().toElement();

    if(dataEle.tagName()!="data")
        return;

    QDomNodeList dataChilds=dataEle.childNodes();
    for(int i=0;i<dataChilds.size();i++)
    {
        QDomElement dataChildEle=dataChilds.at(i).toElement();
        data.dataArrayOp.datas.append(parseIdExpression(dataChildEle));
    }
}

void OperatorImporter::parseChgIthOp(const QDomElement &element,Equation &data)
{
    data.operatorType="ChgIthOp";

    QDomElement flowEle=element.firstChild().toElement();
    if(flowEle.tagName()!="flow")
        return;

    QDomElement withEle=element.firstChild().nextSibling().toElement();
    if(withEle.tagName()!="with")
        return;

    QDomElement valueEle=element.firstChild().nextSibling().nextSibling().toElement();
    if(valueEle.tagName()!="value")
        return;

    data.chgIthOp.flow=parseIdExpression(flowEle.firstChild().toElement());

    QDomNodeList withChilds=withEle.childNodes();
    for(int i=0;i<withChilds.size();i++)
    {
        if(!withChilds.at(i).isComment())
        {
            QDomElement withChildEle=withChilds.at(i).toElement();

            if(withChildEle.tagName()!="Label")
            {
                data.chgIthOp.parameters.append(parseParameter(withChildEle));
            }
            else
            {
                parameter para;
                para.value=withChildEle.attribute("name");
                data.chgIthOp.parameters.append(para);
            }

        }
    }

    data.chgIthOp.value=parseIdExpression(valueEle.firstChild().toElement());
}

void OperatorImporter::parseIfThenElseOp(const QDomElement &element,Equation &data)
{
    data.operatorType="IfThenElseOp";

    QDomElement ifEle=element.firstChild().toElement();
    if(ifEle.tagName()!="if")
        return;

    QDomElement thenEle=element.firstChild().nextSibling().toElement();
    if(thenEle.tagName()!="then")
        return;

    QDomElement elseEle=element.firstChild().nextSibling().nextSibling().toElement();
    if(elseEle.tagName()!="else")
        return;

    data.ifThenElseOp.ifValue=parseIdExpression(ifEle.firstChild().toElement());

    QDomNodeList thenChilds=thenEle.firstChild().firstChild().childNodes();
    for(int i=0;i<thenChilds.size();i++)
    {
        QDomElement thenChildEle=thenChilds.at(i).toElement();
        data.ifThenElseOp.thens.append(parseIdExpression(thenChildEle));
    }

    QDomNodeList elseChilds=elseEle.firstChild().firstChild().childNodes();
    for(int i=0;i<elseChilds.size();i++)
    {
        QDomElement elseChildEle=elseChilds.at(i).toElement();
        data.ifThenElseOp.elses.append(parseIdExpression(elseChildEle));
    }
}

void OperatorImporter::parseCaseOp(const QDomElement &element,Equation &data)
{
    data.operatorType="CaseOp";

    QDomElement switchEle=element.firstChild().toElement();
    if(switchEle.tagName()!="switch")
        return;

    QDomElement casesEle=element.firstChild().nextSibling().toElement();
    if(casesEle.tagName()!="cases")
        return;

    data.caseOp.switchValue=parseIdExpression(switchEle.firstChild().toElement());

    QDomNodeList casesChilds=casesEle.childNodes();
    for(int i=0;i<(casesChilds.size()-1);i++)
    {
        QDomElement casesChildEle=casesChilds.at(i).toElement();

        label item;
        item.labelName=casesChildEle.attribute("pattern");
        item.value=parseIdExpression(casesChildEle.firstChild().firstChild().toElement());
        data.caseOp.cases.append(item);
    }

    data.caseOp.defaultValue=parseIdExpression(casesChilds.at(casesChilds.size()).toElement());
}

void OperatorImporter::parseMakeOp(const QDomElement &element,Equation &data)
{
    data.operatorType="MakeOp";

    QDomElement operatorEle=element.firstChild().toElement();
    if(operatorEle.tagName()!="operator")
        return;

    QDomElement callsEle=operatorEle.nextSibling().toElement();

    data.makeOp.typeRef=operatorEle.firstChild().firstChild().firstChild().toElement().attribute("name");

    QDomNodeList callsChilds=callsEle.childNodes();
    for(int i=0;i<callsChilds.size();i++)
    {
        QDomElement callsChildEle=callsChilds.at(i).toElement();
        data.makeOp.calls.append(parseIdExpression(callsChildEle));
    }
}

void OperatorImporter::parseFlattenOp(const QDomElement &element,Equation &data)
{
    data.operatorType="FlattenOp";

    QDomElement operatorEle=element.firstChild().toElement();
    if(operatorEle.tagName()!="operator")
        return;

    QDomElement callsEle=element.firstChild().nextSibling().toElement();
    if(callsEle.tagName()!="callParameters")
        return;

    data.flattenOp.typeRef=operatorEle.firstChild().firstChild().firstChild().toElement().attribute("name");

    data.flattenOp.call=parseIdExpression(callsEle.firstChild().toElement());

}

void OperatorImporter::parseNumericCastOp(const QDomElement &element, Equation &data)
{
    data.operatorType="NumericCastOp";

    QDomElement typeEle=element.namedItem("type").toElement();
    QDomElement flowEle=element.namedItem("flow").toElement();

    data.numericCastOp.typeRef=typeEle.firstChildElement().attribute("name");
    data.numericCastOp.flow=parseParameter(flowEle.firstChildElement());
}

void OperatorImporter::parseTransposeOp(const QDomElement &element, Equation &data)
{
    data.operatorType="TransposeOp";

    QDomElement arrayEle=element.namedItem("array").toElement();
    QDomElement dimensionsEle=element.namedItem("dimensions").toElement();

    data.transposeOp.array=parseIdExpression(arrayEle.firstChildElement());
    data.transposeOp.dimension1=parseParameter(dimensionsEle.firstChildElement());
    data.transposeOp.dimension2=parseParameter(dimensionsEle.firstChildElement().nextSiblingElement());
}

void OperatorImporter::parseActivateOp(const QDomElement &element, Equation &data)
{
    data.operatorType="ActivateOp";

    QDomNode firstOperatorNode=element.namedItem("operator");
    QDomNode callParametersNode=element.namedItem("callParameters");
    QDomNode ActivateOpNode=firstOperatorNode.firstChild();
    QDomNode secondOperatorNode=ActivateOpNode.namedItem("operator");
    QDomNode everyNode=ActivateOpNode.namedItem("every");
    QDomNode defaultNode=ActivateOpNode.namedItem("default");
    QDomNode opCallNode=secondOperatorNode.namedItem("OpCall");
    QDomNode thirdOperatorNode=opCallNode.namedItem("operator");
    QDomNode operatorRefNode=thirdOperatorNode.namedItem("OperatorRef");
    QDomNode listExpressionNode=defaultNode.namedItem("ListExpression");
    QDomNode itemsNode=listExpressionNode.namedItem("items");

    if(ActivateOpNode.toElement().tagName()=="ActivateOp")
    {
        data.activateOp.isInit=true;
    }
    else if(ActivateOpNode.toElement().tagName()=="ActivateNoInitOp")
    {
        data.activateOp.isInit=false;
    }

    if(!operatorRefNode.isNull())
    {
        data.activateOp.operatorRef=operatorRefNode.toElement().attribute("name");

        //判断是否为自定义操作符
        if(data.activateOp.operatorRef.at(data.activateOp.operatorRef.length()-1)=='$')
        {
            data.activateOp.isRef=false;
        }
        else {
            data.activateOp.isRef=true;
        }
    }

    if(secondOperatorNode.firstChild().toElement().tagName()=="MakeOp")
    {
        m_operator.logList.append("存在REDACE不支持的Make的高阶操作符;");
        data.isUnsupport=true;
        data.activateOp.isMakeOp=true;
        data.activateOp.makeRef=secondOperatorNode.firstChild().firstChild().firstChild().toElement().attribute("name");
    }

    if(secondOperatorNode.firstChild().toElement().tagName()=="FlattenOp")
    {
        m_operator.logList.append("存在REDACE不支持的Flatten的高阶操作符;");
        data.isUnsupport=true;
        data.activateOp.isFlattenOp=true;
        data.activateOp.flattenRef=secondOperatorNode.firstChild().firstChild().firstChild().toElement().attribute("name");
    }


    data.activateOp.every=parseIdExpression(everyNode.firstChildElement());

    for(int i=0;i<itemsNode.childNodes().size();i++)
    {
        QDomElement defaultItemEle=itemsNode.childNodes().at(i).toElement();
        data.activateOp.defaultValue.append(parseParameter(defaultItemEle));
    }

    for(int i=0;i<callParametersNode.childNodes().size();i++)
    {
        QDomElement callEle=callParametersNode.childNodes().at(i).toElement();
        data.activateOp.calls.append(parseIdExpression(callEle));
    }
}

void OperatorImporter::parseRestartOp(const QDomElement &element, Equation &data)
{
    data.operatorType="RestartOp";

    QDomNode firstOperatorNode=element.namedItem("operator");
    QDomNode callParametersNode=element.namedItem("callParameters");
    QDomNode RestartOpNode=firstOperatorNode.firstChild();
    QDomNode secondOperatorNode=RestartOpNode.namedItem("operator");
    QDomNode everyNode=RestartOpNode.namedItem("every");
    QDomNode opCallNode=secondOperatorNode.namedItem("OpCall");
    QDomNode thirdOperatorNode=opCallNode.namedItem("operator");
    QDomNode operatorRefNode=thirdOperatorNode.namedItem("OperatorRef");

    if(!operatorRefNode.isNull())
    {
        data.restartOp.operatorRef=operatorRefNode.toElement().attribute("name");

        //判断是否为自定义操作符
        if(data.restartOp.operatorRef.at(data.restartOp.operatorRef.length()-1)=='$')
        {
            data.restartOp.isRef=false;
        }
        else {
            data.restartOp.isRef=true;
        }
    }

    if(secondOperatorNode.firstChild().toElement().tagName()=="MakeOp")
    {
        m_operator.logList.append("存在REDACE不支持的Make的高阶操作符;");
        data.isUnsupport=true;
        data.restartOp.isMakeOp=true;
        data.restartOp.makeRef=secondOperatorNode.firstChild().firstChild().firstChild().toElement().attribute("name");
    }

    if(secondOperatorNode.firstChild().toElement().tagName()=="FlattenOp")
    {
        m_operator.logList.append("存在REDACE不支持的Flatten的高阶操作符;");
        data.isUnsupport=true;
        data.restartOp.isFlattenOp=true;
        data.restartOp.flattenRef=secondOperatorNode.firstChild().firstChild().firstChild().toElement().attribute("name");
    }


    data.restartOp.every=parseIdExpression(everyNode.firstChildElement());

    for(int i=0;i<callParametersNode.childNodes().size();i++)
    {
        QDomElement callEle=callParametersNode.childNodes().at(i).toElement();
        data.restartOp.calls.append(parseIdExpression(callEle));
    }

}

void OperatorImporter::parseIteratorOp(const QDomElement &element,Equation &data)
{
    data.operatorType="IteratorOp";

    QDomElement operatorEle=element.firstChild().toElement();
    if(operatorEle.tagName()!="operator")
        return;

    QDomElement callsEle=operatorEle.nextSibling().toElement();

    QDomElement iteratorEle=operatorEle.firstChild().toElement();

    data.iteratorOp.iteratorType=iteratorEle.attribute("iterator");

    if(data.iteratorOp.iteratorType=="mapfoldi")
    {
        m_operator.logList.append("存在REDACE不支持的mapfoldi高阶操作符;");
    }

    if(data.iteratorOp.iteratorType=="mapfold"&&iteratorEle.attribute("accumulatorCount")!="1")
    {
        m_operator.logList.append("存在mapfold操作符的accumulatorCount值不等于1;");
    }

    operatorEle=iteratorEle.firstChild().toElement();
    if(operatorEle.tagName()!="operator")
        return;

    QDomElement sizeEle=operatorEle.nextSibling().toElement();
    if(sizeEle.tagName()!="size")
        return;

    QDomElement ele=operatorEle.firstChild().toElement();

    //组合操作符或用户操作符
    if(ele.tagName()=="OpCall")
    {
        data.iteratorOp.operatorRef=ele.firstChild().firstChild().toElement().attribute("name");

        //判断是否为自定义操作符
        if(data.iteratorOp.operatorRef.at(data.iteratorOp.operatorRef.length()-1)=='$')
        {
            data.iteratorOp.isRef=false;
        }
        else {
            data.iteratorOp.isRef=true;
        }
    }

    //Make
    if(ele.tagName()=="MakeOp")
    {
        m_operator.logList.append("存在REDACE不支持的Make的高阶操作符;");
        data.isUnsupport=true;
        data.iteratorOp.isMakeOp=true;
        data.iteratorOp.makeRef=ele.firstChild().firstChild().toElement().attribute("name");
    }

    //Flatten
    if(ele.tagName()=="FlattenOp")
    {
        m_operator.logList.append("存在REDACE不支持的Flatten的高阶操作符;");
        data.isUnsupport=true;
        data.iteratorOp.isFlattenOp=true;
        data.iteratorOp.flattenRef=ele.firstChild().firstChild().toElement().attribute("name");
    }

    if(sizeEle.childNodes().size()==2)
    {
        data.iteratorOp.size=parseParameter(sizeEle.childNodes().at(1).toElement());
    }
    else {
        data.iteratorOp.size=parseParameter(sizeEle.firstChild().toElement());
    }

    if(data.iteratorOp.size.value==m_operator.parameter)
        data.isParaHigh=true;

    QDomNodeList callsChilds=callsEle.childNodes();
    for(int i=0;i<callsChilds.size();i++)
    {
        QDomElement callsChildEle=callsChilds.at(i).toElement();
        data.iteratorOp.calls.append(parseIdExpression(callsChildEle));
    }

    if(data.iteratorOp.isRef==true)
    {
        opcallOperator opcall;
        opcall.operatorName=m_operator.operatorName;
        opcall.opcallName=data.iteratorOp.operatorRef;

        opcall.equation=data;
        m_operator.opCallList.append(opcall);
    }
}

void OperatorImporter::parsePartialIteratorOp(const QDomElement &element,Equation &data)
{
    data.operatorType="PartialIteratorOp";

    QDomElement operatorEle=element.firstChild().toElement();
    if(operatorEle.tagName()!="operator")
        return;

    QDomElement callsEle=operatorEle.nextSibling().toElement();


    QDomElement partialIteratorEle=operatorEle.firstChild().toElement();

    data.partialIteratorOp.partialIteratorType=partialIteratorEle.attribute("iterator");

    if(data.partialIteratorOp.partialIteratorType=="mapfoldw")
    {
        m_operator.logList.append("存在REDACE不支持的mapfoldw高阶操作符;");
    }

    if(data.partialIteratorOp.partialIteratorType=="mapfoldwi")
    {
        m_operator.logList.append("存在REDACE不支持的mapfoldwi高阶操作符;");
    }

    operatorEle=partialIteratorEle.firstChild().toElement();
    if(operatorEle.tagName()!="operator")
        return;

    QDomElement sizeEle=operatorEle.nextSibling().toElement();
    if(sizeEle.tagName()!="size")
        return;

    QDomElement ifEle=sizeEle.nextSibling().toElement();
    if(ifEle.tagName()!="if")
        return;

    QDomElement defaultEle=ifEle.nextSibling().toElement();

    if(!defaultEle.isNull())
    {
        QDomElement listExpressionEle=defaultEle.namedItem("ListExpression").toElement();
        QDomElement itemsEle=listExpressionEle.namedItem("items").toElement();

        for(int i=0;i<itemsEle.childNodes().size();i++)
        {
            QDomNode node=itemsEle.childNodes().at(i);
            if(!node.isComment())
            {
                data.partialIteratorOp.defaultValue.append(parseParameter(node.toElement()));
            }
        }

        if(!data.partialIteratorOp.defaultValue.isEmpty())
        {
            data.partialIteratorOp.hasDefault=true;
        }
    }

    QDomElement ele=operatorEle.firstChild().toElement();

    //组合操作符或用户操作符
    if(ele.tagName()=="OpCall")
    {
        data.partialIteratorOp.operatorRef=ele.firstChild().firstChild().toElement().attribute("name");

        //判断是否为自定义操作符
        if(data.partialIteratorOp.operatorRef.at(data.partialIteratorOp.operatorRef.length()-1)=='$')
        {
            data.partialIteratorOp.isRef=false;
        }
        else {
            data.partialIteratorOp.isRef=true;
        }
    }

    //Make
    if(ele.tagName()=="MakeOp")
    {
        m_operator.logList.append("存在REDACE不支持的Make的高阶操作符;");
        data.isUnsupport=true;
        data.partialIteratorOp.isMakeOp=true;
        data.partialIteratorOp.makeRef=ele.firstChild().firstChild().toElement().attribute("name");
    }

    //Flatten
    if(ele.tagName()=="FlattenOp")
    {
        m_operator.logList.append("存在REDACE不支持的Flatten的高阶操作符;");
        data.isUnsupport=true;
        data.partialIteratorOp.isFlattenOp=true;
        data.partialIteratorOp.flattenRef=ele.firstChild().firstChild().toElement().attribute("name");
    }

    //    data.partialIteratorOp.size=sizeEle.firstChild().toElement().attribute("value");

    if(sizeEle.childNodes().size()==2)
    {
        data.partialIteratorOp.size=parseParameter(sizeEle.childNodes().at(1).toElement());
    }
    else {
        data.partialIteratorOp.size=parseParameter(sizeEle.firstChild().toElement());
    }

    if(data.partialIteratorOp.size.value==m_operator.parameter)
        data.isParaHigh=true;

    data.partialIteratorOp.ifValue=parseIdExpression(ifEle.firstChild().toElement());

    QDomNodeList callsChilds=callsEle.childNodes();
    for(int i=0;i<callsChilds.size();i++)
    {
        QDomElement callsChildEle=callsChilds.at(i).toElement();
        data.partialIteratorOp.calls.append(parseIdExpression(callsChildEle));
    }

    if(data.partialIteratorOp.isRef==true)
    {
        opcallOperator opcall;
        opcall.operatorName=m_operator.operatorName;
        opcall.opcallName=data.partialIteratorOp.operatorRef;

        opcall.equation=data;
        m_operator.opCallList.append(opcall);
    }

}

void OperatorImporter::parseOpCall(const QDomElement &element,Equation &data)
{
    data.operatorType="OpCall";

    QDomElement operatorEle;

    operatorEle=element.firstChild().toElement();

    QDomElement instanceParaEle;

    QDomNodeList nodeList=operatorEle.firstChild().childNodes();

    for(int i=0;i<nodeList.size();i++)
    {

        //判断是否包含参数
        if(nodeList.at(i).toElement().tagName()=="instanceParameters")
        {
            data.isParaHigh=true;
            instanceParaEle=nodeList.at(i).toElement();

            if(instanceParaEle.childNodes().size()==2)
            {
                data.paraValue=parseParameter(instanceParaEle.childNodes().at(1).toElement());
            }
            else {
                data.paraValue=parseParameter(instanceParaEle.firstChild().toElement());
            }

        }
    }

    QDomElement callsEle=operatorEle.nextSibling().toElement();

    data.opCall.operatorRef=operatorEle.firstChild().firstChild().firstChild().toElement().attribute("name");

    //保存所有调用的操作符
    opcallOperator opcall;
    opcall.operatorName=m_operator.operatorName;
    opcall.opcallName=data.opCall.operatorRef;

    if(data.isParaHigh==true)
    {
        opcallParaOperator opcall;
        opcall.paraValue=data.paraValue;
        opcall.operatorName=data.opCall.operatorRef;

        data.opCall.operatorRef=opcall.operatorName+"_"+opcall.paraValue.value;

        m_operator.paraOperatorList.append(opcall);
    }

    QDomNodeList callsChilds=callsEle.childNodes();
    for(int i=0;i<callsChilds.size();i++)
    {
        QDomElement callsChildEle=callsChilds.at(i).toElement();
        data.opCall.calls.append(parseIdExpression(callsChildEle));
    }

    opcall.equation=data;
    m_operator.opCallList.append(opcall);

}

QString OperatorImporter::parseIdExpression(const QDomElement &element)
{
    QString refName;
    QDomNode pathNode=element.firstChild();

    if(pathNode.toElement().tagName()!="path")
    {
        return refName;
    }

    if(pathNode.firstChild().isNull())
        return refName;

    QDomElement constVarRefEle=pathNode.firstChild().toElement();

    if(constVarRefEle.tagName()=="NullRef")
        return refName;

    if(constVarRefEle.tagName()=="ConstVarRef"&&constVarRefEle.hasAttribute("name"))
    {
        refName=constVarRefEle.attribute("name");

    }

    return refName;

}

parameter OperatorImporter::parseParameter(const QDomElement &element)
{
    parameter para;

    para.node=element;
    //立即数
    if(element.tagName()=="ConstValue")
    {
        para.isImmediate=true;
        para.value=element.attribute("value");
    }

    //非立即数
    if(element.tagName()=="IdExpression")
    {
        para.value=parseIdExpression(element);
    }

    //表达式
    if(para.value.isEmpty())
    {
        para.isImmediate=true;
        para.value=element.previousSibling().nodeValue();
    }

    return para;
}

void OperatorImporter::generateOperatorFileTemplate(const QString &redaceProjectPath, const QString &scadeProjectName, const QString &operatorFileName, OperatorData &datas)
{
    QString filePath=redaceProjectPath+"/"+scadeProjectName+"/"+operatorFileName;
    QFile file(filePath);
    QFileInfo fileInfo=QFileInfo(filePath);

    if(!file.open(QFile::WriteOnly|QFile::Truncate))
        return;

    QXmlStreamWriter writer(&file);

    writer.setAutoFormatting(true);
    writer.setAutoFormattingIndent(2);

    //写入StartDocument
    writer.writeStartDocument();

    //写File节点
    writer.writeStartElement("File");
    writer.writeAttribute("Type","Operator");

    //declarations
    writer.writeStartElement("declarations");

    //Operator
    writer.writeStartElement("Operator");
    writer.writeAttribute("kind",datas.kind);

    if(datas.isImported==true)
        writer.writeAttribute("external","imported");

    writer.writeAttribute("name",datas.operatorName);

    //operator_property
    writer.writeStartElement("operator_property");
    writer.writeAttribute("description",datas.comment);
    writer.writeAttribute("subFolderName","");
    writer.writeAttribute("isInSubFolder","False");

    if(!datas.stmList.isEmpty())
    {
        writer.writeAttribute("isStateMachine","true");
    }

    if(datas.isImported==false)
    {
        writer.writeAttribute("isImportOpe","false");
        writer.writeAttribute("cFilePath","");
        writer.writeAttribute("hFilePath","");
    }
    else
    {
        writer.writeAttribute("isImportOpe","true");
        writer.writeAttribute("cFilePath",redaceProjectPath+"/"+scadeProjectName+"/acg_imported/"+datas.operatorName+".c");
        writer.writeAttribute("hFilePath",redaceProjectPath+"/"+scadeProjectName+"/acg_imported/"+datas.operatorName+".h");
    }


    writer.writeAttribute("stylePath","");
    writer.writeEndElement();//结束operator_property

    //oid
    writer.writeStartElement("oid");
    m_operator.redaceOid=QUuid::createUuid().toString(QUuid::WithoutBraces);
    writer.writeAttribute("value",m_operator.redaceOid);
    writer.writeEndElement();//结束oid

    //data
    writer.writeStartElement("data");
    writer.writeEndElement();

    //diagrams
    writer.writeStartElement("diagrams");
    for(int i=0;i<datas.diagrams.size();i++)
    {
        writer.writeStartElement("NetDiagram");
        writer.writeAttribute("name",datas.diagrams.at(i).name);
        writer.writeAttribute("landscape",datas.diagrams.at(i).landscape);
        writer.writeAttribute("oid",datas.diagrams.at(i).redaceOid);
        writer.writeAttribute("EleIDIndex","");
        writer.writeAttribute("OutPortIndex","");
        writer.writeAttribute("ProjectName","");
        writer.writeAttribute("DiagramName","");
        writer.writeAttribute("DiagramId","");
        writer.writeAttribute("Description","");
        writer.writeAttribute("DiagramNum","");
        writer.writeAttribute("DiagramVersion","");
        writer.writeAttribute("DesignPersonName","");
        writer.writeAttribute("DesignTime","");
        writer.writeAttribute("CheckPersonName","");
        writer.writeAttribute("CheckTime","");
        writer.writeAttribute("DeterminePersonName","");
        writer.writeAttribute("DetermineTime","");
        writer.writeAttribute("ApprovePersonName","");
        writer.writeAttribute("ApproveTime","");
        writer.writeAttribute("FDDiagram","False");
        writer.writeAttribute("BackgroundImageWidth","0");
        writer.writeAttribute("BackgroundImageHeight","0");
        writer.writeAttribute("BackgroundImageFileName","");

        writer.writeEndElement();
    }
    writer.writeEndElement();

    writer.writeEndElement();//结束data

    writer.writeEndElement();//结束Operator

    writer.writeEndElement();//结束declarations

    writer.writeEndElement();//结束File

    writer.writeEndDocument();

    file.close();

}

void OperatorImporter::generateStmPOUFiles()
{
    for(auto item:m_operator.stmModel.statemachines().keys())
    {
        auto stm=m_operator.stmModel.statemachines().value(item);

        //创建文件夹
        QString stmDirPath=stm.projectpath+"/POUs/"+stm.hierarchy;
        QDir dir(stmDirPath);

        if (!dir.exists()) {
            if (dir.mkpath(stmDirPath)) {
                qDebug() << "文件夹已创建:" << stmDirPath;
            } else {
                qDebug() << "无法创建文件夹:" << stmDirPath;
                    return;
            }
        } else {
            qDebug() << "文件夹已存在:" << stmDirPath;
        }

        //保存POU文件
        m_operator.stmModel.saveSTMToPOU(stm.redaceOid,stmDirPath+"/"+stm.poufilename);

    }


}

void OperatorImporter::variableProcess(QList<Variable> &vars,QDomDocument &doc)
{
    QMap<QString,QString> suffix;
    suffix["short"]="s";
    suffix["int64"]="l";
    suffix["float"]="f";
    suffix["ushort"]="us";
    suffix["uint"]="u";
    suffix["uint64"]="ul";

    //变量处理
    for(int i=0;i<vars.size();i++)
    {
        if(m_hash.contains(vars.at(i).dataType))
        {
            vars[i].dataType=m_hash.value(vars.at(i).dataType);
        }


        QDomNode varNode=vars.at(i).node;

        QDomNodeList nodeList=varNode.childNodes();

        QDomNode typeNode=varNode.namedItem("type");
        QDomNode defaultNode=varNode.namedItem("default");
        QDomNode lastNode=varNode.namedItem("last");
        QDomNode pragmasNode=varNode.namedItem("pragmas");
        QDomNode idNode=pragmasNode.firstChild();
        QDomNode commentNode=idNode.namedItem("comment");;

        QString oid;//oid
        QString comment;//注释

        //last、default值加后缀
        if(suffix.contains(vars[i].dataType)||vars[i].dataType=="real")
        {
            QRegularExpression regex1("^[-+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][-+]?\\d+)?$");
            QRegularExpression regex2("^[-+]?\\d+$");

            if(!lastNode.isNull())
            {                
                if(regex1.match(vars[i].lastValue).hasMatch())
                {
                    if(regex2.match(vars[i].lastValue).hasMatch()&&vars[i].dataType=="float")
                    {
                        QDomElement lastConstValueEle=lastNode.namedItem("ConstValue").toElement();
                        lastConstValueEle.setAttribute("value",lastConstValueEle.attribute("value")+".0"+suffix.value(vars[i].dataType));
                        vars[i].lastValue=vars[i].lastValue+".0"+suffix.value(vars[i].dataType);
                    }
                    else if(regex2.match(vars[i].lastValue).hasMatch()&&vars[i].dataType=="real")
                    {
                        QDomElement lastConstValueEle=lastNode.namedItem("ConstValue").toElement();
                        lastConstValueEle.setAttribute("value",lastConstValueEle.attribute("value")+".0");
                        vars[i].lastValue=vars[i].lastValue+".0";
                    }
                    else
                    {
                        QDomElement lastConstValueEle=lastNode.namedItem("ConstValue").toElement();
                        lastConstValueEle.setAttribute("value",lastConstValueEle.attribute("value")+suffix.value(vars[i].dataType));
                        vars[i].lastValue=vars[i].lastValue+suffix.value(vars[i].dataType);
                    }
                }
            }

            if(!defaultNode.isNull())
            {
                if(regex1.match(vars[i].defaultValue).hasMatch())
                {
                    if(regex2.match(vars[i].defaultValue).hasMatch()&&vars[i].dataType=="float")
                    {
                        QDomElement defaultConstValueEle=defaultNode.namedItem("ConstValue").toElement();
                        defaultConstValueEle.setAttribute("value",defaultConstValueEle.attribute("value")+".0"+suffix.value(vars[i].dataType));
                        vars[i].defaultValue=vars[i].defaultValue+".0"+suffix.value(vars[i].dataType);
                    }
                    else if(regex2.match(vars[i].defaultValue).hasMatch()&&vars[i].dataType=="real")
                    {
                        QDomElement defaultConstValueEle=defaultNode.namedItem("ConstValue").toElement();
                        defaultConstValueEle.setAttribute("value",defaultConstValueEle.attribute("value")+".0");
                        vars[i].defaultValue=vars[i].defaultValue+".0";
                    }
                    else
                    {
                        QDomElement defaultConstValueEle=defaultNode.namedItem("ConstValue").toElement();
                        defaultConstValueEle.setAttribute("value",defaultConstValueEle.attribute("value")+suffix.value(vars[i].dataType));
                        vars[i].defaultValue=vars[i].defaultValue+suffix.value(vars[i].dataType);
                    }
                }
            }
        }

        oid=QUuid::createUuid().toString(QUuid::WithoutBraces);
        vars[i].id=oid;

        if(!commentNode.isNull())
            comment=commentNode.toElement().text();

        varNode.removeChild(pragmasNode);

        QDomElement oidEle=doc.createElement("oid");
        oidEle.setAttribute("value",oid);
        varNode.appendChild(oidEle);

        if(!comment.isEmpty())
        {
            QDomElement pragmasEle=doc.createElement("pragmas");
            varNode.appendChild(pragmasEle);

            QDomElement commentEle=doc.createElement("comment");
            commentEle.setAttribute("value",comment);
            pragmasEle.appendChild(commentEle);
        }

        QDomNode indexNode=typeNode.firstChild();

        //处理变量的数据类型引用了包中的数据类型
        if(indexNode.toElement().tagName()=="NamedType")
        {
            QDomNode typeRefNode=indexNode.firstChild().firstChild();

            if(typeRefNode.toElement().tagName()=="TypeRef")
            {
                    QString name=typeRefNode.toElement().attribute("name");

                    if(typeRefNode.toElement().attribute("name").contains("::"))
                    {
                    QStringList list=name.split("::");
                    name=list.at(list.size()-1);
                    typeRefNode.toElement().setAttribute("name",name);
                    }


                    if(m_hash.contains(name))
                    {
                    typeRefNode.toElement().setAttribute("name",m_hash.value(name));
                    }


            }
        }

        //处理结构体变量的结构体元素的oid
        if(indexNode.toElement().tagName()=="Struct")
        {
            QDomNode fieldsNode=indexNode.firstChild();

            QDomNodeList nodeList=fieldsNode.childNodes();

            for(int i=0;i<nodeList.size();i++)
            {
                    QDomNode node=nodeList.at(i);

                    QDomNodeList fieldChild=node.childNodes();

                    for(int i=0;i<fieldChild.size();i++)
                    {
                    QDomNode childNode=fieldChild.at(i);

                    if(childNode.toElement().tagName()=="type")
                    {
                        QDomNode fieldType=childNode.firstChild();
                        if(fieldType.toElement().tagName()=="NamedType")
                        {
                            QString type=fieldType.firstChild().firstChild().toElement().attribute("name");
                            if(m_hash.contains(type))
                            {
                                fieldType.firstChild().firstChild().toElement().setAttribute("name",m_hash.value(type));
                            }
                        }

                        //结构体嵌套结构体
                        if(fieldType.toElement().tagName()=="Struct")
                        {
                            QDomNode fieldsNode=fieldType.firstChild();
                            QDomNodeList nodeList=fieldsNode.childNodes();

                            for(int i=0;i<nodeList.size();i++)
                            {
                                QDomNode node=nodeList.at(i);
                                QDomNodeList fieldChild=node.childNodes();

                                for(int i=0;i<fieldChild.size();i++)
                                {
                                    QDomNode childNode=fieldChild.at(i);

                                    if(childNode.toElement().tagName()=="pragmas")
                                    {
                                        QDomNode fieldOid=childNode;

                                        fieldOid.toElement().setTagName("oid");

                                        fieldOid.toElement().setAttribute("value",QUuid::createUuid().toString(QUuid::WithoutBraces));

                                        fieldOid.removeChild(fieldOid.firstChild());
                                    }
                                }

                            }
                        }
                    }

                    if(childNode.toElement().tagName()=="pragmas")
                    {
                        QDomNode fieldOid=childNode;

                        fieldOid.toElement().setTagName("oid");

                        fieldOid.toElement().setAttribute("value",QUuid::createUuid().toString(QUuid::WithoutBraces));

                        fieldOid.removeChild(fieldOid.firstChild());
                    }
                    }
            }
        }

        //处理结构体数组中结构体元素的oid
        if(indexNode.toElement().tagName()=="Table")
        {
            QDomNode index=indexNode.firstChild().firstChild();

            if(index.toElement().tagName()=="NamedType")
            {
                    QString type=index.firstChild().firstChild().toElement().attribute("name");
                    if(m_hash.contains(type))
                    {
                    index.firstChild().firstChild().toElement().setAttribute("name",m_hash.value(type));
                    }

                    //去除::
                    if(type.contains("::"))
                    {
                    QStringList strList=type.split("::");
                    index.firstChild().firstChild().toElement().setAttribute("name",strList.last());
                    }
            }

            if(index.toElement().tagName()=="Struct")
            {
                    QDomNode fieldsNode=index.firstChild();

                    QDomNodeList nodeList=fieldsNode.childNodes();

                    for(int i=0;i<nodeList.size();i++)
                    {
                    QDomNode node=nodeList.at(i);

                    QDomNodeList fieldChild=node.childNodes();

                    for(int i=0;i<fieldChild.size();i++)
                    {
                        QDomNode childNode=fieldChild.at(i);

                        if(childNode.toElement().tagName()=="pragmas")
                        {
                            QDomNode fieldOid=childNode;

                            fieldOid.toElement().setTagName("oid");

                            fieldOid.toElement().setAttribute("value",QUuid::createUuid().toString(QUuid::WithoutBraces));

                            fieldOid.removeChild(fieldOid.firstChild());
                        }
                    }
                    }
            }
        }

        vars[i].node=varNode;
    }    
}

void OperatorImporter::dataStreamEquationProcess(OperatorData &datas, QDomDocument &doc)
{
    for(int i=0;i<datas.equations.size();i++)
    {

        Equation equation=datas.equations.at(i);

        if(equation.type=="emitSignal")
        {
            emissionProcess(equation,doc);
        }
        else
        {
            equationProcess(equation,doc);
        }

        datas.equations[i]=equation;
    }
}

void OperatorImporter::stmEquationProcess(QDomDocument &doc)
{
    for(auto state:m_operator.stmModel.states().values())
    {
        for(int i=0;i<state.equations.size();i++)
        {

            Equation equation=state.equations.at(i);

            if(equation.type=="emitSignal")
            {
                emissionProcess(equation,doc);
            }
            else
            {
                equationProcess(equation,doc);
            }

            state.equations[i]=equation;
        }

        m_operator.stmModel.addState(state.redaceOid,state);
    }
}

void OperatorImporter::blockEquationProcess(QDomDocument &doc)
{
    for(auto &action:m_operator.blockModel.actionMap)
    {
        for(int i=0;i<action.equations.size();i++)
        {
            Equation equation=action.equations.at(i);

            if(equation.type=="emitSignal")
            {
                emissionProcess(equation,doc);
            }
            else
            {
                equationProcess(equation,doc);
            }

            action.equations[i]=equation;
        }

        for(auto& pou:action.pouList)
        {
            for(auto& equation:pou.dia.equations)
            {
                if(equation.type=="emitSignal")
                {
                    emissionProcess(equation,doc);
                }
                else
                {
                    equationProcess(equation,doc);
                }
            }
        }
    }
}

void OperatorImporter::equationProcess(Equation &equation, QDomDocument &doc)
{
    QDomNode equationNode=equation.node.cloneNode(true);

    if(!equation.pageId.isEmpty())
    {
        equationNode.toElement().setAttribute("oid",equation.pageId);
    }

    QDomNode leftsNode;

    QDomNode rightNode;

    QDomNode pragmasNode;

    for(int j=0;j<equationNode.childNodes().size();j++)
    {
        if(equationNode.childNodes().at(j).toElement().tagName()=="lefts")
            leftsNode=equationNode.childNodes().at(j);

        if(equationNode.childNodes().at(j).toElement().tagName()=="right")
        {
            rightNode=equationNode.childNodes().at(j);

            //'\x00'改为'/x00'
            if(equation.type=="immediate"&&equation.rightVarRef=="'\\x00'")
            {
                QDomNode constValueNode=rightNode.firstChild();
                constValueNode.toElement().setAttribute("value","'/x00'");
            }

            //整数或浮点数加后缀
            if(equation.type=="immediate")
            {
                QMap<QString,QString> suffix;
                suffix["int8"]="s";
                suffix["int16"]="s";
                suffix["int64"]="l";
                suffix["float32"]="f";
                suffix["uint8"]="us";
                suffix["uint16"]="us";
                suffix["uint32"]="u";
                suffix["uint64"]="ul";

                QRegularExpression regex("^[-+]?\\d+$");
                QDomElement ConstValueEle=rightNode.namedItem("ConstValue").toElement();

                if(suffix.contains(equation.immediateType))
                {
                    if(regex.match(ConstValueEle.attribute("value")).hasMatch()&&equation.immediateType=="float32")
                    {
                        ConstValueEle.setAttribute("value",ConstValueEle.attribute("value")+".0"+suffix[equation.immediateType]);
                    }
                    else
                    {
                        ConstValueEle.setAttribute("value",ConstValueEle.attribute("value")+suffix[equation.immediateType]);
                    }
                }

                if(regex.match(ConstValueEle.attribute("value")).hasMatch()&&equation.immediateType=="float64")
                {                    
                    ConstValueEle.setAttribute("value",ConstValueEle.attribute("value")+".0");
                }
            }

            //删除引用的自定义操作符的pragmas节点
            if(equation.operatorType=="MakeOp"
                    ||equation.operatorType=="FlattenOp"
                    ||equation.operatorType=="IteratorOp"
                    ||equation.operatorType=="PartialIteratorOp"
                    ||equation.operatorType=="ActivateOp"
                    ||equation.operatorType=="RestartOp"
                    ||equation.operatorType=="OpCall")
            {
                QDomNode callExpressionNode=rightNode.namedItem("CallExpression");
                QDomNode pragmasNode=callExpressionNode.namedItem("pragmas");

                if(!pragmasNode.isNull())
                {
                    callExpressionNode.removeChild(pragmasNode);
                }
            }

            //修改cast操作符数据类型
            if(equation.operatorType=="NumericCastOp")
            {
                QDomNode castOpNode=rightNode.namedItem("NumericCastOp");
                QDomNode typeNode=castOpNode.namedItem("type");
                QDomNode typeRefNode=typeNode.namedItem("TypeRef");

                if((!typeRefNode.isNull())&&m_hash.contains(equation.numericCastOp.typeRef))
                {
                    typeRefNode.toElement().setAttribute("name",m_hash[equation.numericCastOp.typeRef]);
                }
            }

            //修改cast立即数
            if(equation.type=="immediate")
            {
                QDomNode castOpNode=rightNode.namedItem("NumericCastOp");
                QDomNode typeNode=castOpNode.namedItem("type");
                QDomNode typeRefNode=typeNode.namedItem("TypeRef");
                QString type=typeRefNode.toElement().attribute("name");

                if((!typeRefNode.isNull())&&m_hash.contains(type))
                {
                    typeRefNode.toElement().setAttribute("name",m_hash[type]);
                }
            }

            //删除mapfold中的accumulatorCount属性值等于1时的accumulatorCount属性
            if(equation.operatorType=="IteratorOp"&&equation.iteratorOp.iteratorType=="mapfold")
            {
                QDomNode CallExpressionNode=rightNode.namedItem("CallExpression");
                QDomNode operatorNode=CallExpressionNode.namedItem("operator");
                QDomNode opNode=operatorNode.firstChild();

                if(opNode.toElement().attribute("accumulatorCount")=="1")
                {
                    opNode.toElement().removeAttribute("accumulatorCount");
                }
            }

            //修改除法
            if(equation.operatorName=="Polymorphic Division")
            {
                QDomNode binaryOpNode=rightNode.namedItem("BinaryOp");
                binaryOpNode.toElement().setAttribute("operator","pdiv");
            }

            if(equation.iteratorOp.operatorRef=="$/$"||equation.partialIteratorOp.operatorRef=="$/$"||equation.activateOp.operatorRef=="$/$")
            {
                QDomNode callExpressionNode=rightNode.namedItem("CallExpression");
                QDomNode operatorNode=callExpressionNode.namedItem("operator");
                QDomNode opNode=operatorNode.namedItem("IteratorOp");
                QDomNode secondOperatorNode=opNode.namedItem("operator");
                QDomNode opCallNode=secondOperatorNode.namedItem("OpCall");
                QDomNode thirdOperatorNode=opCallNode.namedItem("operator");
                QDomNode operatorRefNode=thirdOperatorNode.namedItem("OperatorRef");

                if(!operatorRefNode.isNull())
                {
                    operatorRefNode.toElement().setAttribute("name","$pdiv$");
                }
            }

            if(equation.operatorType=="OpCall")
            {
                QDomNode opCallNode=rightNode.childNodes().at(1).firstChild().firstChild();

                QDomNodeList nodeList=opCallNode.childNodes();

                for(int i=0;i<nodeList.size();i++)
                {
                    QDomNode node=nodeList.at(i);

                    if(node.toElement().tagName()=="operator")
                    {
                        QDomNode operatorRefNode=node.firstChild();

                        QString operatorRefName=operatorRefNode.toElement().attribute("name");

                        if(operatorRefName.contains("::"))
                        {
                            QStringList list=operatorRefName.split("::");

                            operatorRefName=list.at(list.size()-1);
                            operatorRefNode.toElement().setAttribute("name",operatorRefName);

                        }

                    }

                    if(node.toElement().tagName()=="pragmas")
                    {
                        opCallNode.removeChild(node);
                    }
                }
            }

            //修改调用了含参数的操作符的equation
            if(equation.isParaHigh&&m_operator.hasPara==false)
            {

                QDomNodeList nodeList=rightNode.childNodes();

                QDomNode callExpressionNode;

                QDomNode opCallNode;

                for(int i=0;i<nodeList.size();i++)
                {
                    if(!nodeList.at(i).isComment())
                    {
                        callExpressionNode=nodeList.at(i);
                    }
                }

                opCallNode=callExpressionNode.firstChild().firstChild();

                nodeList=opCallNode.childNodes();

                for(int i=0;i<nodeList.size();i++)
                {

                    if(nodeList.at(i).toElement().tagName()=="operator")
                    {
                        opCallNode.childNodes().at(i).firstChild().toElement().setAttribute("name",opCallNode.childNodes().at(i).firstChild().toElement().attribute("name")+"_"+equation.paraValue.value);
                    }
                }

                opCallNode.removeChild(opCallNode.childNodes().at(1));
                callExpressionNode.firstChild().firstChild()=opCallNode;
                rightNode.childNodes().at(1)=callExpressionNode;

            }

            equationNode.childNodes().at(j)=rightNode;
        }

        if(equationNode.childNodes().at(j).toElement().tagName()=="pragmas")
            pragmasNode=equationNode.childNodes().at(j);
    }

    QDomNode idNode=pragmasNode.firstChild();

    QDomNode commentNode=idNode.firstChild();

    QString comment;//注释

    if(!commentNode.isNull())
        comment=commentNode.toElement().text();

    equationNode.removeChild(pragmasNode);

    QDomElement oidEle=doc.createElement("oid");
    oidEle.setAttribute("value",equation.redaceId);
    equationNode.appendChild(oidEle);

    if(!comment.isEmpty())
    {
        QDomElement pragmasEle=doc.createElement("pragmas");
        equationNode.appendChild(pragmasEle);

        QDomElement commentEle=doc.createElement("comment");
        commentEle.setAttribute("value",comment);
        pragmasEle.appendChild(commentEle);
    }

    equation.node=equationNode;
}

bool OperatorImporter::castImmediateProcess(QString &str)
{
    // 创建临时字符串副本并移除所有空格
    QString temp = str;
    temp.remove(QRegularExpression("\\s"));

    // 定义正则表达式匹配整个格式
    QRegularExpression regex(R"(^\(([^:]+):(\w+)\)$)");
    QRegularExpressionMatch match = regex.match(temp);

    if (!match.hasMatch()) {
        return false; // 格式不匹配
    }

    // 获取匹配的数值和类型部分
    QString valuePart = match.captured(1);
    QString originalType = match.captured(2);

    // 验证数据类型是否有效
    static const QStringList validTypes = {
        "int8", "int16", "int32", "int64",
        "uint8", "uint16", "uint32", "uint64",
        "float32", "float64"
    };

    if (!validTypes.contains(originalType)) {
        return false; // 无效的数据类型
    }

    // 如果提供了替换映射，则替换类型部分
    if (!m_hash.isEmpty()) {
        // 检查映射表中是否有该类型的替换
        if (m_hash.contains(originalType)) {
            QString newType = m_hash.value(originalType);

            // 在原始字符串中查找类型位置（忽略空格）
            int startPos = -1;
            int length = originalType.length();

            // 查找冒号位置
            int colonPos = str.indexOf(':');
            if (colonPos == -1) return false;

            // 从冒号后开始查找类型字符串
            for (int i = colonPos + 1; i < str.length(); i++) {
                if (!str[i].isSpace()) {
                    if (startPos == -1) startPos = i;
                    if (str.mid(startPos, length) == originalType) {
                        // 替换原始字符串中的类型部分
                        str.replace(startPos, length, newType);
                        break;
                    }
                }
            }
        }
    }

    return true;
}

void OperatorImporter::emissionProcess(Equation &equation, QDomDocument &doc)
{
    QDomNode equationNode=equation.node.cloneNode(true);

//    if(!equation.pageId.isEmpty())
//    {
//        equationNode.toElement().setAttribute("oid",equation.pageId);
//    }

    QDomNode pragmasNode=equationNode.namedItem("pragmas");

    QDomNode idNode=pragmasNode.namedItem("ed:Emission");

    QDomNode commentNode=idNode.namedItem("comment");

    QString comment;//注释

    if(!commentNode.isNull())
        comment=commentNode.toElement().text();

    equationNode.removeChild(pragmasNode);

    QDomElement oidEle=doc.createElement("oid");
    oidEle.setAttribute("value",equation.redaceId);
    equationNode.appendChild(oidEle);

    if(!comment.isEmpty())
    {
        QDomElement pragmasEle=doc.createElement("pragmas");
        equationNode.appendChild(pragmasEle);

        QDomElement commentEle=doc.createElement("comment");
        commentEle.setAttribute("value",comment);
        pragmasEle.appendChild(commentEle);
    }

    equation.node=equationNode;
}

void OperatorImporter::statemachineProcess(QDomDocument &doc)
{
    //将Transition的tager从Name改回oid;计算优先级
    transitionProcess(doc);

    //位置、大小处理
    stmGEProcess();

    //oid处理
    stmModelOidProcess();
}

void OperatorImporter::ifblockProcess()
{
    ifblockOidProcess();

}

void OperatorImporter::ifblockOidProcess()
{
    QMap<QString,BlockAction> new_actionMap;
    QMap<QString,IfNode> new_ifnodeMap;

    for(auto& block:m_operator.blockModel.ifblockList)
    {
        block.redaceOid=QUuid::createUuid().toString(QUuid::WithoutBraces);
    }

    for(auto action:m_operator.blockModel.actionMap)
    {
        QString newActionOid=QUuid::createUuid().toString(QUuid::WithoutBraces);
        action.redaceOid=newActionOid;
        new_actionMap.insert(action.redaceOid,action);

        for(auto ifnode:m_operator.blockModel.ifNodeMap)
        {
            if(ifnode.thenFork.oid==action.scadeOid)
            {
                ifnode.thenFork.oid=action.redaceOid;
                m_operator.blockModel.ifNodeMap.insert(ifnode.scadeOid,ifnode);
            }

            if(ifnode.elseFork.oid==action.scadeOid)
            {
                ifnode.elseFork.oid=action.redaceOid;
                m_operator.blockModel.ifNodeMap.insert(ifnode.scadeOid,ifnode);
            }
        }
    }

    for(auto ifnode:m_operator.blockModel.ifNodeMap)
    {
        if(ifnode.type==ROOT)
        {
            for(auto& block:m_operator.blockModel.ifblockList)
            {
                if(block.ifNodeOid==ifnode.scadeOid)
                {
                    ifnode.redaceOid=block.redaceOid;//根ifnode的oid与ifblockoid相同
                    block.ifNodeOid=ifnode.redaceOid;
                }
            }
        }
        else
        {
            QString newIfNodeOid=QUuid::createUuid().toString(QUuid::WithoutBraces);
            ifnode.redaceOid=newIfNodeOid;
        }
        new_ifnodeMap.insert(ifnode.redaceOid,ifnode);
    }

    m_operator.blockModel.ifNodeMap=new_ifnodeMap;
    m_operator.blockModel.actionMap=new_actionMap;

    for(auto ifnode:m_operator.blockModel.ifNodeMap)
    {
        for(auto node:m_operator.blockModel.ifNodeMap)
        {
            if(node.thenFork.oid==ifnode.scadeOid)
            {
                node.thenFork.oid=ifnode.redaceOid;
                m_operator.blockModel.ifNodeMap[node.redaceOid]=node;
            }

            if(node.elseFork.oid==ifnode.scadeOid)
            {
                node.elseFork.oid=ifnode.redaceOid;
                m_operator.blockModel.ifNodeMap[node.redaceOid]=node;
            }
        }
    }
}

void OperatorImporter::ifblockInfoProcess()
{

}

void OperatorImporter::generateStmGrammarFiles()
{
    for(auto item:m_operator.stmModel.statemachines().keys())
    {
        auto stm=m_operator.stmModel.statemachines().value(item);

        //创建文件夹
        QString stmDirPath=stm.projectpath+"/POUs/"+stm.hierarchy;

        QString filePath=stmDirPath+"/"+stm.filename;
            // 打开文件以进行写入
            QFile file(filePath);
        if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
            return ; // 文件打开失败，返回空对象
        }

        QXmlStreamWriter stream(&file);
        stream.setAutoFormatting(true);
        stream.writeStartDocument();

        //开始写入StateMachine
        stream.writeStartElement("StateMachine");
        stream.writeAttribute("name",stm.name);

        QString parentDir = QFileInfo(filePath).absolutePath();

        if(stm.statelist.count()>0)
        {
            stream.writeStartElement("states");

            for (int i = 0; i < stm.statelist.count(); ++i)
            {

                WriteStateElement(stream, *m_operator.stmModel.getState(stm.statelist[i]));
            }

            stream.writeEndElement();//结束states
        }

        stream.writeStartElement("oid");
        stream.writeAttribute("value",stm.redaceOid);
        stream.writeEndElement();//结束oid
        stream.writeEndElement();//结束StateMachine
        stream.writeEndDocument();
        file.close();
    }
}

void OperatorImporter::generateStateGrammarFiles()
{
    for(auto state:m_operator.stmModel.states().values())
    {
        StateMachine stm=*m_operator.stmModel.getStateMachine(state.parentid);
        //创建文件夹
        QString stmDirPath=stm.projectpath+"/POUs/"+state.hierarchy;
        QDir dir(stmDirPath);
        if(!dir.exists())
            dir.mkdir(stmDirPath);//创建POUs文件夹

        QDomDocument doc;
        QDomProcessingInstruction header = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
        doc.appendChild(header);

        // 创建根元素 <State>
        QDomElement stateEle = doc.createElement("State");
        doc.appendChild(stateEle);
        stateEle.setAttribute("oid",state.redaceOid);

        QDomElement dataEle=doc.createElement("data");
        stateEle.appendChild(dataEle);

        for(int j=0;j<state.equations.size();j++)
        {
            dataEle.appendChild(state.equations.at(j).node);
        }

        QDomElement diagramsEle=doc.createElement("diagrams");
        stateEle.appendChild(diagramsEle);

        for(int j=0;j<state.pouList.size();j++)
        {
            POU pou=state.pouList.at(j);
            QDomElement NetDiagramEle=doc.createElement("NetDiagram");
            NetDiagramEle.setAttribute("name",pou.name);
            NetDiagramEle.setAttribute("landscape","");
            NetDiagramEle.setAttribute("oid",pou.oid);
            NetDiagramEle.setAttribute("stateName",state.name);
            NetDiagramEle.setAttribute("DiagramType","statediagram");
            NetDiagramEle.setAttribute("stateId",state.redaceOid);
            NetDiagramEle.setAttribute("EleIDIndex","");
            NetDiagramEle.setAttribute("OutPortIndex","");
            NetDiagramEle.setAttribute("ProjectName","");
            NetDiagramEle.setAttribute("DiagramName","");
            NetDiagramEle.setAttribute("DiagramId","");
            NetDiagramEle.setAttribute("Description","");
            NetDiagramEle.setAttribute("DiagramNum","");
            NetDiagramEle.setAttribute("DiagramVersion","");
            NetDiagramEle.setAttribute("DesignPersonName","");
            NetDiagramEle.setAttribute("DesignTime","");
            NetDiagramEle.setAttribute("CheckPersonName","");
            NetDiagramEle.setAttribute("CheckTime","");
            NetDiagramEle.setAttribute("DeterminePersonName","");
            NetDiagramEle.setAttribute("DetermineTime","");
            NetDiagramEle.setAttribute("ApprovePersonName","");
            NetDiagramEle.setAttribute("ApproveTime","");
            NetDiagramEle.setAttribute("FDDiagram","False");
            NetDiagramEle.setAttribute("BackgroundImageWidth","0");
            NetDiagramEle.setAttribute("BackgroundImageHeight","0");
            NetDiagramEle.setAttribute("BackgroundImageFileName","");
            diagramsEle.appendChild(NetDiagramEle);
        }


        QString filePath=stmDirPath+"/"+state.name+".redace";
        QFile file(filePath);

        if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            QTextStream stream(&file);
            stream.setCodec("UTF-8"); // 设置编码
            doc.save(stream, 2, QDomNode::EncodingFromDocument); // 缩进2空格
            file.close();
        }

    }
}

void OperatorImporter::WriteStateElement(QXmlStreamWriter &writer, State &state)
{
    writer.writeStartElement("State");

    if(state.initial)
    {
        writer.writeAttribute("initial",state.initial?"true":"false");
    }
    if(state.final)
    {
        writer.writeAttribute("final",state.final?"true":"false");
    }

    writer.writeAttribute("name",state.name);

    //WriteStateOpDataElement(writer,statename);

    if(!state.trans_strong.isEmpty())
    {
        writer.writeStartElement("unless");

        if(state.trans_strong.count()>0)
        {
            for (int var = 0; var < state.trans_strong.count(); ++var)
            {
                WriteTransitionElement(writer,*m_operator.stmModel.getTransition(state.trans_strong[var]));
            }
        }
        writer.writeEndElement();//结束unless
    }

    if(!state.pouList.isEmpty()||!state.stmList.isEmpty())
    {
        writer.writeStartElement("data");

        for(auto item:state.pouList)
        {
            writer.writeStartElement("POURef");
            writer.writeAttribute("name",item.name);
            writer.writeAttribute("oid",item.oid);
            writer.writeAttribute("filePath",item.filePath);
            writer.writeEndElement();//结束POURef
        }

        for(auto item:state.stmList)
        {
            writer.writeStartElement("StateMachineRef");
            writer.writeAttribute("oid",item);
            auto stm=m_operator.stmModel.getStateMachine(item);
            if(stm)
            {
                writer.writeAttribute("name",stm->name);
                writer.writeAttribute("filePath","/POUs/"+stm->hierarchy+"/"+stm->poufilename);
            }
            writer.writeEndElement();//结束StateMachineRef
        }

        writer.writeEndElement();//结束data
    }

    if(state.trans_weak.count()>0||state.trans_sync.count()>0)
    {
        writer.writeStartElement("until");
        for (int var = 0; var < state.trans_weak.count(); ++var)
        {
            WriteTransitionElement(writer,*m_operator.stmModel.getTransition(state.trans_weak[var]));
        }
        //待讨论同步迁移
        if(state.trans_sync.count()>0)
        {
            for (int var = 0; var < state.trans_sync.count(); ++var)
            {
                WriteSynchroTransitionElement(writer, *m_operator.stmModel.getTransition(state.trans_sync[var]));
            }
        }
        writer.writeEndElement();//结束until
    }

    writer.writeStartElement("oid");
    writer.writeAttribute("value",state.redaceOid);
    writer.writeEndElement();//结束oid
    writer.writeEndElement();//结束state
}

QByteArray elementInnerXml(const QDomElement &element)
{
    if (element.isNull())
        return QByteArray();

    // 只获取元素的子节点 XML
    QDomDocument tempDoc;
    tempDoc.appendChild(tempDoc.importNode(element, true));

    return tempDoc.toByteArray(2); // 带缩进
}

void OperatorImporter::WriteTransitionElement(QXmlStreamWriter &writer, Transition &transition)
{
    writer.writeStartElement("Transition");
    QString kindvalue;
    switch (transition.history) {
    case 0:
        kindvalue= "restart";
        break;
    case 1:
        kindvalue = "resume";
        break;
    default:
        break;
    }
    writer.writeAttribute("kind",kindvalue);

    writer.writeStartElement("target");
    writer.writeStartElement("StateRef");
    writer.writeAttribute("name",m_operator.stmModel.getState((transition.target))->name);
    writer.writeEndElement();//结束StateRef
    writer.writeEndElement();//结束target

    writer.writeStartElement("condition");

    if (!transition.conditionNode.isNull())
    {
        QDomElement condElement = transition.conditionNode.toElement();

        // 只写入条件元素的内部内容
        QByteArray innerXml = elementInnerXml(condElement);
        if (!innerXml.isEmpty()) {
            writer.writeCharacters(""); // 防止自闭合标签
            writer.writeCharacters("\n");
            writer.device()->write(innerXml);
        }
    }

    writer.writeEndElement();//结束condition

    if(!transition.actions().isEmpty())
    {
        writer.writeStartElement("effect");
        writer.writeStartElement("Action");
        writer.writeStartElement("data");

        for(int i=0;i<transition.actionNodes.size();i++)
        {
            QDomElement ele=transition.actionNodes.at(i).toElement();

            if(ele.tagName()=="Equation"||ele.tagName()=="Emission")
            {
                QByteArray innerXml = elementInnerXml(ele);
                if (!innerXml.isEmpty()) {
                    writer.writeCharacters(""); // 防止自闭合标签
                    writer.writeCharacters("\n");
                    writer.device()->write(innerXml);
                }
            }
        }

        //WriteActionElement(writer,transition.actions());
        writer.writeEndElement();//data
        writer.writeStartElement("oid");
        writer.writeAttribute("value",QUuid::createUuid().toString(QUuid::WithoutBraces));
        writer.writeEndElement();//结束oid
        writer.writeEndElement();//结束Action
        writer.writeEndElement();//结束effect
    }

    writer.writeStartElement("oid");
    writer.writeAttribute("value",transition.oid);
    writer.writeEndElement();//结束oid
    writer.writeEndElement();//结束TransitionNode
}

void OperatorImporter::WriteSynchroTransitionElement(QXmlStreamWriter &writer, Transition &transition)
{
    writer.writeStartElement("Synchro");
    QString kindvalue;
    switch (transition.history) {
    case 0:
        kindvalue= "restart";
        break;
    case 1:
        kindvalue = "resume";
        break;
    default:
        break;
    }
    writer.writeAttribute("kind",kindvalue);

    writer.writeStartElement("target");
    writer.writeStartElement("StateRef");
    writer.writeAttribute("name",m_operator.stmModel.getState((m_operator.stmModel.getTransition(transition.oid)->target))->name);
    writer.writeEndElement();//结束StateRef
    writer.writeEndElement();//结束target

    if(!transition.actions().isEmpty())
    {
        writer.writeStartElement("effect");
        writer.writeStartElement("Action");
        writer.writeStartElement("data");
        //WriteActionElement(writer,transition.actions());
        writer.writeEndElement();//data
        writer.writeStartElement("oid");
        writer.writeAttribute("value",QUuid::createUuid().toString(QUuid::WithoutBraces));
        writer.writeEndElement();//结束oid
        writer.writeEndElement();//结束Action
        writer.writeEndElement();//结束effect
    }

    writer.writeStartElement("oid");
    writer.writeAttribute("value",transition.oid);
    writer.writeEndElement();//结束oid
    writer.writeEndElement();//结束Synchro

}

void OperatorImporter::stmGEProcess()
{
    //位置、大小处理
    for(const auto& key:m_operator.stmModel.statemachines().keys() )
    {
        StateMachine stm=m_operator.stmModel.statemachines().value(key);

        stm.rect.setWidth((stm.rect.width()/20)+100);
        stm.rect.setHeight((stm.rect.height()/20)+100);
        m_operator.stmModel.addStateMachine(stm.scadeOid,stm);

        for(const auto &stateOid:stm.statelist)
        {
            if(m_operator.stmModel.states().contains(stateOid))
            {
                State state=*m_operator.stmModel.getState(stateOid);

                state.ge.rect.setRect((state.ge.rect.x()-stm.rect.x())/16,(state.ge.rect.y()-stm.rect.y())/16,state.ge.rect.width()/16,state.ge.rect.height()/16);
                m_operator.stmModel.addState(state.scadeOid,state);

            }
        }

        for(const auto &stateOid:stm.statelist)
        {
            if(m_operator.stmModel.states().contains(stateOid))
            {
                State state=*m_operator.stmModel.getState(stateOid);

                for(const auto& transOid:state.trans_strong+state.trans_weak+state.trans_sync)
                {
                    if(m_operator.stmModel.trans().contains(transOid))
                    {
                        Transition trans=*m_operator.stmModel.getTransition(transOid);
                        QPoint startPoint=trans.ge.path.first();
                        QPoint endPoint=trans.ge.path.last();

                        startPoint.setX((startPoint.x()-stm.rect.x())/16);
                        startPoint.setY((startPoint.y()-stm.rect.y())/16);
                        endPoint.setX((endPoint.x()-stm.rect.x())/16);
                        endPoint.setY((endPoint.y()-stm.rect.y())/16);

                        startPoint=findNearestPointSafe(state.ge.rect,startPoint);

                        if(m_operator.stmModel.states().contains(trans.target))
                        {
                            State targetState=*m_operator.stmModel.getState(trans.target);
                            endPoint=findNearestPointSafe(targetState.ge.rect,endPoint);
                        }

                        //计算两个控制点
                        // 计算向量差
                        QPoint delta = endPoint - startPoint;

                        // 计算两个三等分点
                        QPoint firstControlPoint = startPoint + (delta) / 3.0;
                        QPoint secondControlPoint = startPoint + 2.0 * (delta) / 3.0;

                        trans.ge.path.clear();
                        trans.ge.path<<startPoint<<firstControlPoint<<secondControlPoint<<endPoint;

                        m_operator.stmModel.addTrans(trans);
                    }
                }

            }
        }
    }

}

void OperatorImporter::transitionProcess(QDomDocument &doc)
{
    //获取target状态的id，并处理action节点
    for(const auto &transOid:m_operator.stmModel.trans().keys())
    {
        Transition trans=*m_operator.stmModel.getTransition(transOid);
        State sourceState=*m_operator.stmModel.getState(trans.source);
        QString stmOid=sourceState.parentid;
        StateMachine stm=*m_operator.stmModel.getStateMachine(stmOid);

        for(auto stateOid:stm.statelist)
        {
            State state=*m_operator.stmModel.getState(stateOid);
            if(state.name==trans.target)
            {
                trans.target=state.scadeOid;
                m_operator.stmModel.addTrans(trans);
            }
        }

        //action节点处理
        for(int i=0;i<trans.actionNodes.size();i++)
        {
            QDomNode node=trans.actionNodes.at(i).cloneNode(true);

            if(node.toElement().tagName()=="Equation")
            {
                Equation equation;
                equation.node=node;
                equationProcess(equation,doc);
                //添加oid
                QDomNode oidNode=equation.node.namedItem("oid");
                oidNode.toElement().setAttribute("value",QUuid::createUuid().toString(QUuid::WithoutBraces));

                trans.actionNodes[i]=equation.node.cloneNode(true);
            }

            if(node.toElement().tagName()=="Emission")
            {
                QDomElement pragmas=node.namedItem("pragmas").toElement();
                node.removeChild(pragmas);
                QDomElement oidEle=doc.createElement("oid");
                oidEle.setAttribute("value",QUuid::createUuid().toString(QUuid::WithoutBraces));
                node.appendChild(oidEle);
                trans.actionNodes[i]=node.cloneNode(true);
            }
        }

        m_operator.stmModel.addTrans(trans);

    }

    for(const auto &stateOid:m_operator.stmModel.states().keys())
    {
        State state=*m_operator.stmModel.getState(stateOid);

        QVector<QString> transList=state.trans_strong+state.trans_weak+state.trans_sync;

        for(int i=0;i<transList.size();i++)
        {
            Transition trans=*m_operator.stmModel.getTransition(transList.at(i));
            trans.prior=i+1;
            m_operator.stmModel.addTrans(trans);
        }
    }


}

void OperatorImporter::stmModelOidProcess()
{
    QMap<QString,StateMachine> new_stms;
    QMap<QString, State> new_states;
    QMap<QString, Transition> new_trans;

    //stmoid
    for(const auto &stmOid:m_operator.stmModel.statemachines().keys())
    {
        StateMachine stm=*m_operator.stmModel.getStateMachine(stmOid);
        QString newStmOid=QUuid::createUuid().toString(QUuid::WithoutBraces);
        m_operator.stmList.replaceInStrings(stm.scadeOid,newStmOid);
        stm.redaceOid=newStmOid;
        stm.operatorOid=m_operator.redaceOid;
        stm.projectid=m_operator.projectOid;
        if(stm.parentType=="operator")
        {
            stm.parentOid=m_operator.redaceOid;
        }

        for(auto &stateOid:stm.statelist)
        {
            State state=*m_operator.stmModel.getState(stateOid);
            state.parentid=newStmOid;
            state.redaceOid=QUuid::createUuid().toString(QUuid::WithoutBraces);

            stateOid.replace(stateOid,state.redaceOid);

            for(auto &transOid:state.trans_strong)
            {
                Transition trans=*m_operator.stmModel.getTransition(transOid);
                QString newTransOid=QUuid::createUuid().toString(QUuid::WithoutBraces);
                transOid.replace(transOid,newTransOid);
                trans.oid=newTransOid;
                trans.source=state.redaceOid;
                new_trans.insert(trans.oid,trans);
            }

            for(auto &transOid:state.trans_weak)
            {
                Transition trans=*m_operator.stmModel.getTransition(transOid);
                QString newTransOid=QUuid::createUuid().toString(QUuid::WithoutBraces);
                transOid.replace(transOid,newTransOid);
                trans.oid=newTransOid;
                trans.source=state.redaceOid;
                new_trans.insert(trans.oid,trans);
            }

            for(auto &transOid:state.trans_sync)
            {
                Transition trans=*m_operator.stmModel.getTransition(transOid);
                QString newTransOid=QUuid::createUuid().toString(QUuid::WithoutBraces);
                transOid.replace(transOid,newTransOid);
                trans.oid=newTransOid;
                trans.source=state.redaceOid;
                new_trans.insert(trans.oid,trans);
            }

            new_states.insert(state.redaceOid,state);
        }

        for(auto item:new_trans.keys())
        {
            Transition trans=new_trans.value(item);

            for(auto key:new_states.keys())
            {
                State state=new_states.value(key);

                if(trans.target==state.scadeOid)
                {
                    trans.target=state.redaceOid;
                }
            }

            new_trans.insert(trans.oid,trans);
        }

        new_stms.insert(stm.redaceOid,stm);
    }

    //更新state的stmlist,stm的parentid
    for(const auto &stateOid:new_states.keys())
    {
        State state=new_states.value(stateOid);

        for(QString& stmOid:state.stmList)
        {
            for(const auto &item:new_stms.keys())
            {
                StateMachine stm=new_stms.value(item);
                if(stmOid==stm.scadeOid)
                {
                    stmOid=stm.redaceOid;
                    new_stms[item].parentOid=state.redaceOid;
                }
            }
        }

        new_states[stateOid]=state;
    }

    m_operator.stmModel.setStms(new_stms);
    m_operator.stmModel.setStates(new_states);
    m_operator.stmModel.setTransitions(new_trans);

}

QPoint OperatorImporter::findNearestPointSafe(const QRect& rect, const QPoint& point) {
    if (rect.isEmpty()) {
        return rect.topLeft();
    }

    const int left = rect.left();
    const int right = rect.left() + rect.width() - 1;
    const int top = rect.top();
    const int bottom = rect.top() + rect.height() - 1;

    const int x = (point.x() < left) ? left :
                      (point.x() > right) ? right : point.x();

    const int y = (point.y() < top) ? top :
                      (point.y() > bottom) ? bottom : point.y();

    return QPoint(x, y);
}

QString OperatorImporter::parseStateMachine(const QDomElement &element,const QList<QDomNode>& equationGEList,const QString &parentStateOid)
{
    StateMachine stm;

    stm.name=element.attribute("name");
    stm.filename=stm.name+".redace";
    stm.poufilename=stm.name+".xml";    
    stm.projectid=m_operator.projectOid;

    if(parentStateOid.isEmpty())
    {
        stm.parentType="operator";
        stm.hierarchy=m_operator.operatorName+"/"+stm.name;
    }
    else
    {
        State state=*m_operator.stmModel.getState(parentStateOid);
        stm.parentType="state";
        stm.hierarchy=state.hierarchy+"/"+stm.name;
    }

    stm.projectpath=m_operator.projectPath;

    QDomElement statesEle=element.namedItem("states").toElement();
    QDomElement pragmasEle=element.namedItem("pragmas").toElement();
    QDomNodeList stateList=statesEle.childNodes();

    if(!pragmasEle.isNull())
    {
        QDomElement oidEle=pragmasEle.namedItem("ed:StateMachine").toElement();
        stm.scadeOid=oidEle.attribute("oid");

        QDomElement commentEle=oidEle.namedItem("comment").toElement();
        stm.comment=commentEle.attribute("comment");
    }

    for(int i=0;i<stateList.size();i++)
    {
        QDomElement stateEle=stateList.at(i).toElement();
        parseState(stateEle,stm,equationGEList);
    }

    m_operator.stmModel.addStateMachine(stm.scadeOid,stm);

    if(parentStateOid.isEmpty())
    {
        m_operator.stmList.append(stm.scadeOid);
    }

    return stm.scadeOid;
}

void OperatorImporter::parseIfBlock(const QDomElement &element, const QList<QDomNode> &equationGEList)
{
    IfBlock block;
    IfNode ifNode;

    QDomNode rootIfNode=element.namedItem("block").namedItem("IfNode");
    QDomNode ifNodePragmasNode=rootIfNode.namedItem("pragmas");
    QDomNode blockPragmasNode=element.namedItem("pragmas");
    QDomNode ifNodeOidNode=ifNodePragmasNode.namedItem("ed:IfNode");
    QDomNode blockOidNode=blockPragmasNode.namedItem("ed:IfBlock");

    block.name=element.attribute("name");
    block.ifNodeOid=ifNodeOidNode.toElement().attribute("oid");
    block.scadeOid=blockOidNode.toElement().attribute("oid");

    parseIfNode(rootIfNode.toElement(),equationGEList);

    m_operator.blockModel.ifblockList.append(block);
}

IfNodeFork OperatorImporter::parseIfNodeFork(const QDomElement &element, const QList<QDomNode> &equationGEList)
{
    IfNodeFork nodeFork;
    QDomNode pragmasNode=element.namedItem("pragmas");
    QDomNode oidNode;

    if(element.tagName()=="IfNode")
    {
        oidNode=pragmasNode.namedItem("ed:IfNode");
        nodeFork.fork=IFNODE;
        parseIfNode(element,equationGEList);
    }

    if(element.tagName()=="Action")
    {
        oidNode=pragmasNode.namedItem("ed:Action");
        nodeFork.fork=ACTION;
        parseIfBlockAction(element,equationGEList);
    }

    nodeFork.oid=oidNode.toElement().attribute("oid");
    return nodeFork;
}

void OperatorImporter::parseIfNode(const QDomElement &element, const QList<QDomNode> &equationGEList)
{
    IfNode ifNode;

    QDomElement parentEle=element.parentNode().toElement();
    QDomElement IfEle=element.namedItem("if").toElement();
    QDomElement ThenEle=element.namedItem("then").toElement();
    QDomElement ElseEle=element.namedItem("else").toElement();
    QDomElement pragmasEle=element.namedItem("pragmas").toElement();
    QDomElement oidEle=pragmasEle.namedItem("ed:IfNode").toElement();

    ifNode.scadeOid=oidEle.attribute("oid");

    //解析IfNode的条件
    QDomNode indexNode=IfEle.firstChild();

    if(indexNode.isComment())
    {
        ifNode.condition=indexNode.toComment().data().trimmed();

        ifNode.conditionNode=IfEle.childNodes().at(1);
    }
    else
    {
        if(indexNode.toElement().tagName()=="IdExpression")
        {
            if(indexNode.firstChildElement().tagName()=="path"&&indexNode.firstChildElement().firstChildElement().tagName()=="ConstVarRef")
            {
                ifNode.condition=indexNode.firstChildElement().firstChildElement().attribute("name");
            }

        }

        if(indexNode.toElement().tagName()=="ConstValue")
        {
            ifNode.condition=indexNode.toElement().attribute("value");
        }

        if(indexNode.toElement().tagName()=="Present")
        {
            ifNode.condition=indexNode.firstChildElement().firstChildElement().attribute("name");
        }

        ifNode.conditionNode=indexNode;
    }

    if(parentEle.tagName()=="block")
    {
        ifNode.type=ROOT;
    }
    else if(parentEle.tagName()=="then")
    {
        ifNode.type=THEN;
    }
    else if(parentEle.tagName()=="else")
    {
        ifNode.type=ELSE;
    }

    ifNode.thenFork=parseIfNodeFork(ThenEle.firstChildElement(),equationGEList);
    ifNode.elseFork=parseIfNodeFork(ElseEle.firstChildElement(),equationGEList);

    m_operator.blockModel.ifNodeMap.insert(ifNode.scadeOid,ifNode);
}

void OperatorImporter::parseIfBlockAction(const QDomElement &element, const QList<QDomNode> &equationGEList)
{
    BlockAction action;

    QList<QDomNode> newEquationGEList=equationGEList;
    QDomElement parentEle=element.parentNode().toElement();
    QDomElement signalsEle=element.namedItem("signals").toElement();
    QDomElement localsEle=element.namedItem("locals").toElement();
    QDomElement dataEle=element.namedItem("data").toElement();
    QDomElement pragmasEle=element.namedItem("pragmas").toElement();
    QDomElement oidEle=pragmasEle.namedItem("ed:Action").toElement();
    QDomNode diagramsEle=oidEle.namedItem("diagrams").toElement();

    if(parentEle.tagName()=="then")
    {
        action.type=THEN;
    }
    else if(parentEle.tagName()=="else")
    {
        action.type=ELSE;
    }

    action.scadeOid=oidEle.attribute("oid");

    if(!signalsEle.isNull())
    {
        QDomNodeList signalList=signalsEle.childNodes();
        for(int j=0;j<signalList.size();j++)
        {
            QDomElement signalEle=signalList.at(j).toElement();

            action.variables.append(parseSignal(signalEle));
        }
    }

    if(!localsEle.isNull())
    {
        action.variables.append(parseVariables(localsEle.toElement()));
    }

    if(!dataEle.isNull())
    {
        if(!diagramsEle.isNull())
        {
            QDomNodeList netDiagramList=diagramsEle.childNodes();

            for(int i=0;i<netDiagramList.size();i++)
            {
                QDomElement netDiagramEle=netDiagramList.at(i).toElement();
                QDomNodeList nodeList=netDiagramEle.firstChild().childNodes();

                for(int j=0;j<nodeList.size();j++)
                {
                    if(nodeList.at(j).toElement().tagName()=="EquationGE")
                        newEquationGEList.append(nodeList.at(j));
                }
            }
        }

        QDomNodeList dataList=dataEle.childNodes();
        for(int i=0;i<dataList.size();i++)
        {
            QDomNode node=dataList.at(i);

            if(node.toElement().tagName()=="Equation")
            {
                action.equations.append(parseEquation(node.toElement(),newEquationGEList,action.variables));
            }

            if(node.toElement().tagName()=="Emission")
            {
                Equation data;

                QDomElement signalsEle=node.namedItem("signals").toElement();
                QDomElement conditionEle=node.namedItem("condition").toElement();
                QDomElement pragmasEle=node.namedItem("pragmas").toElement();
                QDomNode idNode=pragmasEle.namedItem("ed:Emission");
                QDomNode commentNode=idNode.namedItem("comment");
                QDomElement signalRefEle=signalsEle.namedItem("SignalRef").toElement();
                QDomElement constVarRef=conditionEle.firstChild().firstChild().firstChild().toElement();

                data.node=node;
                data.oid=getOid(idNode);
                data.redaceId=QUuid::createUuid().toString(QUuid::WithoutBraces);
                data.comment=getComment(commentNode);
                data.type="emitSignal";
                data.name=signalRefEle.attribute("name");
                data.lefts.append(data.name);
                data.rightVarRef=constVarRef.attribute("name");
                action.equations.append(data);
            }

            //报告嵌套ifblock和whenblock
            if(node.toElement().tagName()=="IfBlock")
            {
                m_operator.logList.append("存在IfBlock嵌套IfBlock");
            }

            if(node.toElement().tagName()=="WhenBlock")
            {
                m_operator.logList.append("存在IfBlock嵌套WhenBlock");
            }
        }

        if(diagramsEle.isNull())
        {
            POU pou;
            pou.name="ifblock_diagram"+QString::number(m_operator.ifblockDiaNum);
            m_operator.ifblockDiaNum++;
            pou.oid=QUuid::createUuid().toString(QUuid::WithoutBraces);
            pou.filePath=m_operator.operatorName;
            action.pouList.append(pou);
        }
        else
        {
            QDomNodeList netDiagramList=diagramsEle.childNodes();

            for(int i=0;i<netDiagramList.size();i++)
            {
                POU pou;
                pou.oid=QUuid::createUuid().toString(QUuid::WithoutBraces);
                pou.filePath=m_operator.operatorName;
                action.pouList.append(pou);
                m_operator.blockModel.actionMap.insert(action.scadeOid,action);
                QDomElement netDiagramEle=netDiagramList.at(i).toElement();
                Diagram diag=parseDiagram(netDiagramEle,i);
                action=m_operator.blockModel.actionMap.value(action.scadeOid);
                action.pouList[i].name=diag.name;
            }
        }

    }
    else
    {
        POU pou;
        pou.name="ifblock_diagram"+QString::number(m_operator.ifblockDiaNum);
        m_operator.ifblockDiaNum++;
        pou.oid=QUuid::createUuid().toString(QUuid::WithoutBraces);
        pou.filePath=m_operator.operatorName;
        action.pouList.append(pou);
    }

    m_operator.blockModel.actionMap.insert(action.scadeOid,action);
}

Variable OperatorImporter::parseSignal(const QDomElement &element)
{
    QDomNode pragmasNode=element.namedItem("pragmas");
    QDomNode idNode=pragmasNode.namedItem("ed:Signal");
    QDomNode commentNode=idNode.namedItem("comment");

    Variable var;
    var.type="signal";
    var.node=element;
    var.id=idNode.toElement().attribute("oid");
    var.name=element.attribute("name");
    var.comment=commentNode.toElement().text();

    return var;
}

void OperatorImporter::parseState(const QDomElement &element, StateMachine &stm,const QList<QDomNode>& equationGEList)
{
    QList<QDomNode> newEquationGEList=equationGEList;
    State state;
    state.name=element.attribute("name");
    state.parentid=stm.scadeOid;
    state.hierarchy=stm.hierarchy+"/"+state.name;

    if(element.hasAttribute("initial")&&element.attribute("initial")=="true")
    {
        state.initial=true;
    }
    else
    {
        state.initial=false;
    }

    if(element.hasAttribute("final")&&element.attribute("final")=="true")
    {
        state.final=true;
    }
    else
    {
        state.final=false;
    }

    QDomNode signalsNode=element.namedItem("signals");
    QDomNode localsNode=element.namedItem("locals");
    QDomNode unlessNode=element.namedItem("unless");
    QDomNode dataNode=element.namedItem("data");
    QDomNode untilNode=element.namedItem("until");
    QDomNode pragmasNode=element.namedItem("pragmas");
    QDomNode diagramsNode;

    if(!pragmasNode.isNull())
    {
        QDomElement oidEle=pragmasNode.namedItem("ed:State").toElement();
        state.scadeOid=oidEle.attribute("oid");
        m_operator.stmModel.addState(state.scadeOid,state);//供嵌套的状态机查询

        stm.statelist.append(state.scadeOid);

        QDomElement commentEle=oidEle.namedItem("comment").toElement();
        state.comment=commentEle.attribute("comment");

        diagramsNode=oidEle.namedItem("diagrams").toElement();
    }

    if(!signalsNode.isNull())
    {
        QDomNodeList signalList=signalsNode.childNodes();
        for(int j=0;j<signalList.size();j++)
        {
            QDomElement signalEle=signalList.at(j).toElement();

            state.variables.append(parseSignal(signalEle));
        }
    }

    if(!localsNode.isNull())
    {
        state.variables.append(parseVariables(localsNode.toElement()));
    }

    if(!unlessNode.isNull())
    {
        QDomNodeList transList=unlessNode.childNodes();
        for(int i=0;i<transList.size();i++)
        {
            parseTransition(transList.at(i).toElement(),state,STRONG);
        }
    }

    if(!dataNode.isNull())
    {
        if(!diagramsNode.isNull())
        {
            QDomNodeList netDiagramList=diagramsNode.childNodes();

            for(int i=0;i<netDiagramList.size();i++)
            {
                QDomElement netDiagramEle=netDiagramList.at(i).toElement();
                QDomNodeList nodeList=netDiagramEle.firstChild().childNodes();

                for(int j=0;j<nodeList.size();j++)
                {
                    if(nodeList.at(j).toElement().tagName()=="EquationGE")
                        newEquationGEList.append(nodeList.at(j));
                }
            }
        }

        QDomNodeList dataList=dataNode.childNodes();
        for(int i=0;i<dataList.size();i++)
        {
            QDomNode node=dataList.at(i);

            if(node.toElement().tagName()=="Equation")
            {
                state.equations.append(parseEquation(node.toElement(),newEquationGEList,state.variables));
            }

            if(node.toElement().tagName()=="Emission")
            {
                Equation data;

                QDomElement signalsEle=node.namedItem("signals").toElement();
                QDomElement conditionEle=node.namedItem("condition").toElement();
                QDomElement pragmasEle=node.namedItem("pragmas").toElement();
                QDomNode idNode=pragmasEle.namedItem("ed:Emission");
                QDomNode commentNode=idNode.namedItem("comment");
                QDomElement signalRefEle=signalsEle.namedItem("SignalRef").toElement();
                QDomElement constVarRef=conditionEle.firstChild().firstChild().firstChild().toElement();

                data.node=node;
                data.oid=getOid(idNode);
                data.redaceId=QUuid::createUuid().toString(QUuid::WithoutBraces);
                data.comment=getComment(commentNode);
                data.type="emitSignal";
                data.name=signalRefEle.attribute("name");
                data.lefts.append(data.name);
                data.rightVarRef=constVarRef.attribute("name");
                state.equations.append(data);
            }

            if(node.toElement().tagName()=="StateMachine")
            {
                state.stmList.append(parseStateMachine(node.toElement(),newEquationGEList,state.scadeOid));
            }

            //报告嵌套ifblock和whenblock
            if(node.toElement().tagName()=="IfBlock")
            {
                m_operator.logList.append("状态机"+stm.name+"存在嵌套IfBlock");
            }

            if(node.toElement().tagName()=="WhenBlock")
            {
                m_operator.logList.append("状态机"+stm.name+"存在嵌套WhenBlock");
            }
        }

        m_operator.stmModel.addState(state.scadeOid,state);

        if(diagramsNode.isNull())
        {
            POU pou;
            pou.name=state.name+"_diagram";
            pou.filePath=state.hierarchy;
            pou.oid=QUuid::createUuid().toString(QUuid::WithoutBraces);
            state.pouList.append(pou);
        }
        else
        {
            QDomNodeList netDiagramList=diagramsNode.childNodes();

            for(int i=0;i<netDiagramList.size();i++)
            {
                POU pou;
                pou.filePath=state.hierarchy;
                pou.oid=QUuid::createUuid().toString(QUuid::WithoutBraces);
                state.pouList.append(pou);
                m_operator.stmModel.addState(state.scadeOid,state);
                QDomElement netDiagramEle=netDiagramList.at(i).toElement();
                Diagram diag=parseDiagram(netDiagramEle,i);
                state=*m_operator.stmModel.getState(state.scadeOid);
                state.pouList[i].name=diag.name;
            }
        }

    }
    else
    {
        POU pou;
        pou.name=state.name+"_diagram";
        pou.filePath=state.hierarchy;
        pou.oid=QUuid::createUuid().toString(QUuid::WithoutBraces);
        state.pouList.append(pou);
    }

    if(!untilNode.isNull())
    {
        QDomNodeList transList=untilNode.childNodes();
        for(int i=0;i<transList.size();i++)
        {
            QDomElement ele=transList.at(i).toElement();

            if(ele.tagName()=="Transition")
            {
                parseTransition(ele,state,WEAK);
            }

            if(ele.tagName()=="Synchro")
            {
                parseTransition(ele,state,SYNCHRO);
            }
        }
    }

    m_operator.stmModel.addState(state.scadeOid,state);
}

void OperatorImporter::parseTransition(const QDomElement &element, State &state, const TransKind &kind)
{
    Transition trans;
    trans.kind=kind;
    trans.source=state.scadeOid;

    if(element.attribute("kind")=="restart")
    {
        trans.history=RESTART;
    }
    else if(element.attribute("kind")=="resume")
    {
        trans.history=RESUME;
    }

    QDomNode targetNode=element.namedItem("target");
    QDomNode conditionNode=element.namedItem("condition");
    QDomNode effectNode=element.namedItem("effect");
    QDomNode pragmasNode=element.namedItem("pragmas");

    if(!targetNode.isNull())
    {
        QDomNode stateRefNode=targetNode.namedItem("StateRef");
        trans.target=stateRefNode.toElement().attribute("name");
    }

    if(!conditionNode.isNull())
    {
        QDomNode indexNode=conditionNode.firstChild();

        if(indexNode.isComment())
        {
            trans.condition_=indexNode.toComment().data().trimmed();

            trans.conditionNode=conditionNode.childNodes().at(1);
        }
        else
        {
            if(indexNode.toElement().tagName()=="IdExpression")
            {
                if(indexNode.firstChildElement().tagName()=="path"&&indexNode.firstChildElement().firstChildElement().tagName()=="ConstVarRef")
                {
                    trans.condition_=indexNode.firstChildElement().firstChildElement().attribute("name");
                }

            }

            if(indexNode.toElement().tagName()=="ConstValue")
            {
                trans.condition_=indexNode.toElement().attribute("value");
            }

            if(indexNode.toElement().tagName()=="Present")
            {
                trans.condition_=indexNode.firstChildElement().firstChildElement().attribute("name");
            }

            trans.conditionNode=indexNode;
        }
    }

    if(!effectNode.isNull())
    {
        QDomNode actionNode=effectNode.namedItem("Action");
        QDomNode dataNode=actionNode.namedItem("data");

        if(!dataNode.isNull())
        {
            QDomNodeList dataList=dataNode.childNodes();

            for(int i=0;i<dataList.size();i++)
            {

                QDomNode node=dataList.at(i);
                trans.actionNodes.append(node);
                if(node.isComment())
                {
                    trans.actions_=trans.actions_+node.nodeValue();
                }
            }
        }
    }


    if(!pragmasNode.isNull())
    {
        QDomElement oidEle;
        if(kind==SYNCHRO)
        {
            oidEle=pragmasNode.namedItem("ed:Synchro").toElement();
        }
        else
        {
            oidEle=pragmasNode.namedItem("ed:Transition").toElement();
        }

        trans.oid=oidEle.attribute("oid");

        if(kind==STRONG)
        {
            state.trans_strong.append(trans.oid);
        }
        else if(kind==WEAK)
        {
            state.trans_weak.append(trans.oid);
        }
        else if(kind==SYNCHRO)
        {
            state.trans_sync.append(trans.oid);
        }

        QDomElement commentEle=oidEle.namedItem("comment").toElement();
        trans.comment=commentEle.attribute("comment");
    }

    m_operator.stmModel.addTrans(trans);
}

void OperatorImporter::parsePragmas(const QDomElement &element)
{
    QDomElement operatorEle=element.firstChild().toElement();
    if(operatorEle.tagName()!="ed:Operator")
        return;

    m_operator.scadeOid=operatorEle.attribute("oid");

    QDomNodeList  operatorChilds=operatorEle.childNodes();
    for(int i=0;i<operatorChilds.size();i++)
    {
        QDomElement operatorChild=operatorChilds.at(i).toElement();

        //comment
        if(operatorChild.tagName()=="comment")
            m_operator.comment=operatorChild.text();

        //diagrams
        if(operatorChild.tagName()=="diagrams")
        {
            QDomNodeList diagramList=operatorChild.childNodes();
            for(int i=0;i<diagramList.size();i++)
            {
                QDomElement diagEle=diagramList.at(i).toElement();

                m_operator.diagrams.append(parseDiagram(diagEle,0));
            }
        }
    }

}

Diagram OperatorImporter::parseDiagram(const QDomElement &element,const int diaIndex)
{
    Diagram diag;
    diag.oid=element.attribute("oid");
    diag.redaceOid=QUuid::createUuid().toString(QUuid::WithoutBraces);
    diag.name=element.attribute("name");
    diag.landscape=element.attribute("landscape");

    if(element.hasChildNodes())
    {
        QDomElement presentationElements=element.firstChild().toElement();

        QDomNodeList equationGEList=presentationElements.childNodes();
        for(int i=0;i<equationGEList.size();i++)
        {
            QDomElement ele=equationGEList.at(i).toElement();
            if(ele.tagName()=="EquationGE")
            {
                QDomElement positionEle=ele.namedItem("position").toElement();
                QDomElement sizeEle=ele.namedItem("size").toElement();
                QDomElement TextAreaEle=ele.namedItem("textAreas").namedItem("TextArea").toElement();

                for(int j=0;j<m_operator.equations.size();j++)
                {
                    if(ele.attribute("presentable")==m_operator.equations.at(j).oid)
                    {
                        m_operator.equations[j].x=positionEle.firstChild().toElement().attribute("x").toInt();
                        m_operator.equations[j].y=positionEle.firstChild().toElement().attribute("y").toInt();
                        m_operator.equations[j].width=sizeEle.firstChild().toElement().attribute("width").toInt();
                        m_operator.equations[j].height=sizeEle.firstChild().toElement().attribute("height").toInt();
                        m_operator.equations[j].pageId=diag.redaceOid;

                        if(!TextAreaEle.isNull()&&m_operator.equations[j].type=="immediate")
                        {
                            m_operator.equations[j].text=TextAreaEle.attribute("text");
                            m_operator.equations[j].text.replace("&#xA;", "").replace("&#xD;", " ").replace("\n", "").replace("\r", " ");
                        }

                        diag.equations.append(m_operator.equations.at(j));
                    }
                }

                for(auto stateOid:m_operator.stmModel.states().keys())
                {
                    State state=*m_operator.stmModel.getState(stateOid);

                    for(int j=0;j<state.equations.size();j++)
                    {
                        if(ele.attribute("presentable")==state.equations.at(j).oid)
                        {
                            state.equations[j].x=positionEle.firstChild().toElement().attribute("x").toInt();
                            state.equations[j].y=positionEle.firstChild().toElement().attribute("y").toInt();
                            state.equations[j].width=sizeEle.firstChild().toElement().attribute("width").toInt();
                            state.equations[j].height=sizeEle.firstChild().toElement().attribute("height").toInt();
                            state.equations[j].pageId=state.pouList.at(diaIndex).oid;

                            if(!TextAreaEle.isNull()&&state.equations[j].type=="immediate")
                            {
                                state.equations[j].text=TextAreaEle.attribute("text");
                                state.equations[j].text.replace("&#xA;", "").replace("&#xD;", " ").replace("\n", "").replace("\r", " ");
                            }

                            state.pouList[diaIndex].dia.equations.append(state.equations.at(j));
                        }
                    }

                    m_operator.stmModel.addState(state.scadeOid,state);
                }

                for(auto actionOid:m_operator.blockModel.actionMap.keys())
                {
                    BlockAction action=m_operator.blockModel.actionMap.value(actionOid);

                    for(int j=0;j<action.equations.size();j++)
                    {
                        if(ele.attribute("presentable")==action.equations.at(j).oid)
                        {
                            action.equations[j].x=positionEle.firstChild().toElement().attribute("x").toInt();
                            action.equations[j].y=positionEle.firstChild().toElement().attribute("y").toInt();
                            action.equations[j].width=sizeEle.firstChild().toElement().attribute("width").toInt();
                            action.equations[j].height=sizeEle.firstChild().toElement().attribute("height").toInt();
                            action.equations[j].pageId=action.pouList.at(diaIndex).oid;

                            if(!TextAreaEle.isNull()&&action.equations[j].type=="immediate")
                            {
                                action.equations[j].text=TextAreaEle.attribute("text");
                                action.equations[j].text.replace("&#xA;", "").replace("&#xD;", " ").replace("\n", "").replace("\r", " ");
                            }

                            action.pouList[diaIndex].dia.equations.append(action.equations.at(j));
                        }
                    }

                    m_operator.blockModel.actionMap.insert(action.scadeOid,action);
                }

            }

            if(ele.tagName()=="Edge")
            {
                Line line;
                line.leftIndex=ele.attribute("leftVarIndex");
                line.rightIndex=ele.attribute("rightExprIndex");
                line.leftEquationOid=ele.attribute("srcEquation");
                line.rightEquationOid=ele.attribute("dstEquation");

                QDomNodeList pointList=ele.firstChild().childNodes();

                //去掉重复的点。奇数重复点去掉，偶数重复点保留
                struct Point
                {
                    int x;
                    int y;
                };

                QList<Point> points;

                for(int j=0;j<pointList.size();j++)
                {
                    Point point;
                    point.x=pointList.at(j).toElement().attribute("x").toInt();
                    point.y=pointList.at(j).toElement().attribute("y").toInt();
                    points.append(point);
                }

                QList<int> indexes;
                for(int j=1;j<points.size();j++)
                {
                    int xL=points.at(j).x-points.at(j-1).x;
                    int yL=points.at(j).y-points.at(j-1).y;

                    if(xL==0&&yL==0&&j%2==0)
                    {
                        indexes.append(j);
                    }
                }

                QList<int> pointRemoveIndex;
                for(int j=0;j<indexes.size();j++)
                {
                    pointRemoveIndex.append(j);
                    //                    points.removeAt(indexes.at(j));
                }

                for(int i=pointRemoveIndex.size()-1;i>=0;i--)
                {
                    points.removeAt(pointRemoveIndex.at(i));
                }

                for(int j=1;j<(points.size()-1);j=j+2)
                {
                    LineLength lineLength;
                    lineLength.hLength=points.at(j).x-points.at(j-1).x;
                    lineLength.zLength=points.at(j+1).y-points.at(j).y;
                    line.lineLengthList.append(lineLength);
                }

                diag.lineList.append(line);

                //状态内的线
                for(auto stateOid:m_operator.stmModel.states().keys())
                {
                    State state=*m_operator.stmModel.getState(stateOid);

                    for(auto item:state.equations)
                    {
                        if(item.oid==line.leftEquationOid)
                        {
                            state.pouList[diaIndex].dia.lineList.append(line);
                        }
                    }

                    m_operator.stmModel.addState(state.scadeOid,state);
                }

                //block中的线
                for(auto& action:m_operator.blockModel.actionMap)
                {
                    for(auto item:action.equations)
                    {
                        if(item.oid==line.leftEquationOid)
                        {
                            action.pouList[diaIndex].dia.lineList.append(line);
                        }
                    }
                }
            }

            if(ele.tagName()=="IfNodeGE")
            {
                QDomElement TextAreaEle=ele.namedItem("textAreas").namedItem("TextArea").toElement();

                for(auto ifnodeOid:m_operator.blockModel.ifNodeMap.keys())
                {
                    if(ifnodeOid==ele.attribute("presentable")&&!TextAreaEle.isNull())
                    {
                        m_operator.blockModel.ifNodeMap[ifnodeOid].condition=TextAreaEle.attribute("text");
                        m_operator.blockModel.ifNodeMap[ifnodeOid].condition.replace("&#xA;", "").replace("&#xD;", " ").replace("\n", "").replace("\r", " ");
                    }
                }

            }

            if(ele.tagName()=="StateMachineGE")
            {
                QString stmOid=ele.attribute("presentable");
                QDomNode positionNode=ele.namedItem("position");
                QDomNode sizeNode=ele.namedItem("size");
                QDomNode pointNode=positionNode.namedItem("Point");
                QDomNode SizeNode=sizeNode.namedItem("Size");

                if(m_operator.stmModel.statemachines().contains(stmOid)&&!pointNode.isNull()&&!SizeNode.isNull())
                {
                    StateMachine stm=*m_operator.stmModel.getStateMachine(stmOid);
                    stm.rect.setRect(pointNode.toElement().attribute("x").toInt(),pointNode.toElement().attribute("y").toInt(),SizeNode.toElement().attribute("width").toInt(),SizeNode.toElement().attribute("height").toInt());
                    m_operator.stmModel.addStateMachine(stm.scadeOid,stm);
                }
            }

            if(ele.tagName()=="StateGE")
            {
                QString stateOid=ele.attribute("presentable");
                QDomNode positionNode=ele.namedItem("position");
                QDomNode sizeNode=ele.namedItem("size");
                QDomNode pointNode=positionNode.namedItem("Point");
                QDomNode SizeNode=sizeNode.namedItem("Size");

                if(m_operator.stmModel.states().contains(stateOid)&&!pointNode.isNull()&&!SizeNode.isNull())
                {
                    State state=*m_operator.stmModel.getState(stateOid);
                    state.ge.rect.setRect(pointNode.toElement().attribute("x").toInt(),pointNode.toElement().attribute("y").toInt(),SizeNode.toElement().attribute("width").toInt(),SizeNode.toElement().attribute("height").toInt());
                    m_operator.stmModel.addState(state.scadeOid,state);
                }
            }

            if(ele.tagName()=="TransitionGE")
            {
                QString transOid=ele.attribute("presentable");
                QDomNode positionsNode=ele.namedItem("positions");
                QDomElement textAreasEle=ele.namedItem("textAreas").toElement();

                if(!positionsNode.isNull())
                {
                    QDomNode firstPointNode=positionsNode.firstChild();
                    QDomNode lastPointNode=positionsNode.lastChild();

                    if(m_operator.stmModel.trans().contains(transOid)&&!firstPointNode.isNull()&&!lastPointNode.isNull())
                    {
                        Transition trans=*m_operator.stmModel.getTransition(transOid);
                        QPoint startPoint(firstPointNode.toElement().attribute("x").toInt(),firstPointNode.toElement().attribute("y").toInt());
                        QPoint endPoint(lastPointNode.toElement().attribute("x").toInt(),lastPointNode.toElement().attribute("y").toInt());
                        trans.ge.path.append(startPoint);
                        trans.ge.path.append(endPoint);

                        if(!textAreasEle.isNull())
                        {
                            for(int i=0;i<textAreasEle.childNodes().size();i++)
                            {
                                QDomElement TextAreaEle=textAreasEle.childNodes().at(i).toElement();
                                if(i==0)
                                {
                                    trans.condition_=TextAreaEle.attribute("text");
                                    trans.condition_.replace("&#xA;", "").replace("&#xD;", " ").replace("\n", "").replace("\r", " ");
                                }

                                if(i==1)
                                {
                                    trans.actions_=TextAreaEle.attribute("text");
                                    trans.actions_.replace("&#xA;", "").replace("&#xD;", " ").replace("\n", "").replace("\r", " ");
                                }
                            }
                        }

                        m_operator.stmModel.addTrans(trans);
                    }
                }

            }

        }
    }

    return diag;
}

bool OperatorImporter::removeXmlComments(const QString& filePath)
{
    // 打开XML文件
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "Failed to open file:" << file.errorString();
        return false;
    }

    // 解析XML内容
    QDomDocument doc;
    QString errorMsg;
    int errorLine, errorColumn;
    if (!doc.setContent(&file, &errorMsg, &errorLine, &errorColumn)) {
        qWarning() << "XML parse error at line" << errorLine << "column" << errorColumn << ":" << errorMsg;
        file.close();
        return false;
    }
    file.close();

    // 递归删除注释节点
    QDomNode root = doc.documentElement();
    removeCommentsRecursive(root);

    // 写回修改后的XML
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
        qWarning() << "Failed to open file for writing:" << file.errorString();
        return false;
    }

    QTextStream out(&file);
    out.setCodec("UTF-8");
    doc.save(out, 4); // 缩进为4个空格
    file.close();

    return true;
}

void OperatorImporter::removeCommentsRecursive(QDomNode& node)
{
    QDomNode child = node.firstChild();
    while (!child.isNull()) {
        QDomNode nextSibling = child.nextSibling();

        if (child.isComment()) {
            // 删除注释节点
            node.removeChild(child);
        } else {
            // 递归处理子节点
            removeCommentsRecursive(child);
        }

        child = nextSibling;
    }
}
